From 0add21078a8bb2b1577bd5e84ec78121fa81f612 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Fri, 6 Sep 2013 13:10:11 -0400 Subject: [PATCH 01/36] Bug 913280 - Electrolysis: Refactor RemoteWebProgress to use a Manager that owns the toplevel and all the sublevel WebProgress objects. r=felipe --- toolkit/content/widgets/remote-browser.xml | 9 +- toolkit/modules/RemoteSecurityUI.jsm | 28 +--- toolkit/modules/RemoteWebProgress.jsm | 156 ++++++++++++--------- 3 files changed, 104 insertions(+), 89 deletions(-) diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml index 0f6b823d7ce8..e1d5e99d050b 100644 --- a/toolkit/content/widgets/remote-browser.xml +++ b/toolkit/content/widgets/remote-browser.xml @@ -38,7 +38,7 @@ @@ -107,8 +108,6 @@ this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true); } - this.webProgress._init(); - let jsm = "resource://gre/modules/RemoteController.jsm"; let RemoteController = Components.utils.import(jsm, {}).RemoteController; this._controller = new RemoteController(this); diff --git a/toolkit/modules/RemoteSecurityUI.jsm b/toolkit/modules/RemoteSecurityUI.jsm index d9747b62ff34..8a8b800ea9d3 100644 --- a/toolkit/modules/RemoteSecurityUI.jsm +++ b/toolkit/modules/RemoteSecurityUI.jsm @@ -13,36 +13,22 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); function RemoteSecurityUI() { - this._state = 0; this._SSLStatus = null; + this._state = 0; } RemoteSecurityUI.prototype = { QueryInterface: XPCOMUtils.generateQI([Ci.nsISSLStatusProvider, Ci.nsISecureBrowserUI]), + // nsISSLStatusProvider + get SSLStatus() { return this._SSLStatus; }, + // nsISecureBrowserUI get state() { return this._state; }, get tooltipText() { return ""; }, - // nsISSLStatusProvider - get SSLStatus() { return this._SSLStatus; }, - - _update: function (state, status) { - let deserialized = null; - if (status) { - let helper = Cc["@mozilla.org/network/serialization-helper;1"] - .getService(Components.interfaces.nsISerializationHelper); - - deserialized = helper.deserializeObject(status) - deserialized.QueryInterface(Ci.nsISSLStatus); - } - - // We must check the Extended Validation (EV) state here, on the chrome - // process, because NSS is needed for that determination. - if (deserialized && deserialized.isExtendedValidation) - state |= Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL; - - this._state = state; - this._SSLStatus = deserialized; + _update: function (aStatus, aState) { + this._SSLStatus = aStatus; + this._state = aState; } }; diff --git a/toolkit/modules/RemoteWebProgress.jsm b/toolkit/modules/RemoteWebProgress.jsm index b26579c5d5db..324583d58c6d 100644 --- a/toolkit/modules/RemoteWebProgress.jsm +++ b/toolkit/modules/RemoteWebProgress.jsm @@ -3,7 +3,7 @@ // 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/. -this.EXPORTED_SYMBOLS = ["RemoteWebProgress"]; +this.EXPORTED_SYMBOLS = ["RemoteWebProgressManager"]; const Ci = Components.interfaces; const Cc = Components.classes; @@ -28,14 +28,13 @@ RemoteWebProgressRequest.prototype = { get URI() { return this.uri.clone(); } }; -function RemoteWebProgress(browser) -{ - this._browser = browser; +function RemoteWebProgress(aManager, aIsTopLevel) { + this._manager = aManager; + this._isLoadingDocument = false; this._DOMWindow = null; - this._isTopLevel = null; + this._isTopLevel = aIsTopLevel; this._loadType = 0; - this._progressListeners = []; } RemoteWebProgress.prototype = { @@ -51,101 +50,132 @@ RemoteWebProgress.prototype = { NOTIFY_REFRESH: 0x00000100, NOTIFY_ALL: 0x000001ff, - _init: function WP_Init() { - this._browser.messageManager.addMessageListener("Content:StateChange", this); - this._browser.messageManager.addMessageListener("Content:LocationChange", this); - this._browser.messageManager.addMessageListener("Content:SecurityChange", this); - this._browser.messageManager.addMessageListener("Content:StatusChange", this); - }, - - _destroy: function WP_Destroy() { - this._browser = null; - }, - get isLoadingDocument() { return this._isLoadingDocument }, get DOMWindow() { return this._DOMWindow; }, get DOMWindowID() { return 0; }, - get isTopLevel() { - // When this object is accessed directly, it's usually obtained - // through browser.webProgress and thus represents the top-level - // document. - // However, during message handling it temporarily represents - // the webProgress that generated the notification, which may or - // may not be a toplevel frame. - return this._isTopLevel === null ? true : this._isTopLevel; - }, + get isTopLevel() { return this._isTopLevel }, get loadType() { return this._loadType; }, - addProgressListener: function WP_AddProgressListener (aListener) { + addProgressListener: function (aListener) { + this._manager.addProgressListener(aListener); + }, + + removeProgressListener: function (aListener) { + this._manager.removeProgressListener(aListener); + } +}; + +function RemoteWebProgressManager (aBrowser) { + this._browser = aBrowser; + this._topLevelWebProgress = new RemoteWebProgress(this, true); + this._progressListeners = []; + + this._browser.messageManager.addMessageListener("Content:StateChange", this); + this._browser.messageManager.addMessageListener("Content:LocationChange", this); + this._browser.messageManager.addMessageListener("Content:SecurityChange", this); + this._browser.messageManager.addMessageListener("Content:StatusChange", this); +} + +RemoteWebProgressManager.prototype = { + get topLevelWebProgress() { + return this._topLevelWebProgress; + }, + + addProgressListener: function (aListener) { let listener = aListener.QueryInterface(Ci.nsIWebProgressListener); this._progressListeners.push(listener); }, - removeProgressListener: function WP_RemoveProgressListener (aListener) { + removeProgressListener: function (aListener) { this._progressListeners = - this._progressListeners.filter(function (l) l != aListener); + this._progressListeners.filter(l => l != aListener); }, - _uriSpec: function (spec) { - if (!spec) - return null; - return new RemoteWebProgressRequest(spec); + _fixSSLStatusAndState: function (aStatus, aState) { + let deserialized = null; + if (aStatus) { + let helper = Cc["@mozilla.org/network/serialization-helper;1"] + .getService(Components.interfaces.nsISerializationHelper); + + deserialized = helper.deserializeObject(aStatus) + deserialized.QueryInterface(Ci.nsISSLStatus); + } + + // We must check the Extended Validation (EV) state here, on the chrome + // process, because NSS is needed for that determination. + if (deserialized && deserialized.isExtendedValidation) + aState |= Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL; + + return [deserialized, aState]; }, - receiveMessage: function WP_ReceiveMessage(aMessage) { - this._isLoadingDocument = aMessage.json.isLoadingDocument; - this._DOMWindow = aMessage.objects.DOMWindow; - this._isTopLevel = aMessage.json.isTopLevel; - this._loadType = aMessage.json.loadType; + receiveMessage: function (aMessage) { + let json = aMessage.json; + let objects = aMessage.objects; - this._browser._contentWindow = aMessage.objects.contentWindow; + // The top-level WebProgress is always the same, but because we don't + // really have a concept of subframes/content we always creat a new object + // for those. + let webProgress = json.isTopLevel ? this._topLevelWebProgress + : new RemoteWebProgress(this, false); + + // The WebProgressRequest object however is always dynamic. + let request = json.requestURI ? new RemoteWebProgressRequest(json.requestURI) + : null; + + // Update the actual WebProgress fields. + webProgress._isLoadingDocument = json.isLoadingDocument; + webProgress._DOMWindow = objects.DOMWindow; + webProgress._loadType = json.loadType; + + if (json.isTopLevel) + this._browser._contentWindow = objects.contentWindow; - let req = this._uriSpec(aMessage.json.requestURI); switch (aMessage.name) { case "Content:StateChange": - for each (let p in this._progressListeners) { - p.onStateChange(this, req, aMessage.json.stateFlags, aMessage.json.status); + for (let p of this._progressListeners) { + p.onStateChange(webProgress, request, json.stateFlags, json.status); } break; case "Content:LocationChange": - let location = newURI(aMessage.json.location); + let location = newURI(json.location); - if (aMessage.json.isTopLevel) { + if (json.isTopLevel) { this._browser.webNavigation._currentURI = location; - this._browser.webNavigation.canGoBack = aMessage.json.canGoBack; - this._browser.webNavigation.canGoForward = aMessage.json.canGoForward; - this._browser._characterSet = aMessage.json.charset; - this._browser._documentURI = newURI(aMessage.json.documentURI); + this._browser.webNavigation.canGoBack = json.canGoBack; + this._browser.webNavigation.canGoForward = json.canGoForward; + this._browser._characterSet = json.charset; + this._browser._documentURI = newURI(json.documentURI); this._browser._imageDocument = null; } - for each (let p in this._progressListeners) { - p.onLocationChange(this, req, location); + for (let p of this._progressListeners) { + p.onLocationChange(webProgress, request, location); } break; case "Content:SecurityChange": - // Invoking this getter triggers the generation of the underlying object, - // which we need to access with ._securityUI, because .securityUI returns - // a wrapper that makes _update inaccessible. - void this._browser.securityUI; - this._browser._securityUI._update(aMessage.json.state, aMessage.json.status); + let [status, state] = this._fixSSLStatusAndState(json.status, json.state); - // The state passed might not be correct due to checks performed - // on the chrome side. _update fixes that. - for each (let p in this._progressListeners) { - p.onSecurityChange(this, req, this._browser.securityUI.state); + if (json.isTopLevel) { + // Invoking this getter triggers the generation of the underlying object, + // which we need to access with ._securityUI, because .securityUI returns + // a wrapper that makes _update inaccessible. + void this._browser.securityUI; + this._browser._securityUI._update(status, state); + } + + for (let p of this._progressListeners) { + p.onSecurityChange(webProgress, request, state); } break; case "Content:StatusChange": - for each (let p in this._progressListeners) { - p.onStatusChange(this, req, aMessage.json.status, aMessage.json.message); + for (let p of this._progressListeners) { + p.onStatusChange(webProgress, request, json.status, json.message); } break; } - - this._isTopLevel = null; } }; From 716d4a98b3c40b37affb9a38a731a15950e01797 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 6 Sep 2013 12:02:51 -0500 Subject: [PATCH 02/36] Bug 893186, part 1 - Fix some code in xpconnect to use JS_HasProperty instead of JS_GetPropertyAttributes. r=bholley. --HG-- extra : rebase_source : 2a9350bfd887fb6000d4f558f79c1a0dc8483efb --- js/xpconnect/src/XPCConvert.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index e339da12e200..a28b16342a73 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -1170,14 +1170,13 @@ XPCConvert::JSValToXPCException(MutableHandleValue s, } - unsigned ignored; bool found; // heuristic to see if it might be usable as an xpcexception - if (!JS_GetPropertyAttributes(cx, obj, "message", &ignored, &found)) - return NS_ERROR_FAILURE; + if (!JS_HasProperty(cx, obj, "message", &found)) + return NS_ERROR_FAILURE; - if (found && !JS_GetPropertyAttributes(cx, obj, "result", &ignored, &found)) + if (found && !JS_HasProperty(cx, obj, "result", &found)) return NS_ERROR_FAILURE; if (found) { From b41f5459f140d6812f6580dee6333578cd1e9238 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 6 Sep 2013 12:02:52 -0500 Subject: [PATCH 03/36] Bug 893186, part 2 - In Interpreter-inl.h, use JSObject::getGenericAttributes instead of JSObject::getPropertyAttributes. r=njn. --HG-- extra : rebase_source : b91f5e77eebd6c71e9d65a651ddc997297959a52 --- js/src/vm/Interpreter-inl.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h index c36e98b97502..fec1e8f79f25 100644 --- a/js/src/vm/Interpreter-inl.h +++ b/js/src/vm/Interpreter-inl.h @@ -275,27 +275,27 @@ DefVarOrConstOperation(JSContext *cx, HandleObject varobj, HandlePropertyName dn JS_StrictPropertyStub, attrs)) { return false; } - } else { + } else if (attrs & JSPROP_READONLY) { /* * Extension: ordinarily we'd be done here -- but for |const|. If we * see a redeclaration that's |const|, we consider it a conflict. */ unsigned oldAttrs; - if (!JSObject::getPropertyAttributes(cx, varobj, dn, &oldAttrs)) - return false; - if (attrs & JSPROP_READONLY) { - JSAutoByteString bytes; - if (AtomToPrintableString(cx, dn, &bytes)) { - JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, - js_GetErrorMessage, - NULL, JSMSG_REDECLARED_VAR, - (oldAttrs & JSPROP_READONLY) - ? "const" - : "var", - bytes.ptr())); - } + RootedId id(cx, NameToId(dn)); + if (!JSObject::getGenericAttributes(cx, varobj, id, &oldAttrs)) return false; + + JSAutoByteString bytes; + if (AtomToPrintableString(cx, dn, &bytes)) { + JS_ALWAYS_FALSE(JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, + js_GetErrorMessage, + NULL, JSMSG_REDECLARED_VAR, + (oldAttrs & JSPROP_READONLY) + ? "const" + : "var", + bytes.ptr())); } + return false; } return true; From 02f654ead7b1a2e2e7fbc20ce62da5e55614b442 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 6 Sep 2013 12:05:28 -0500 Subject: [PATCH 04/36] Bug 893186, part 3 - Add JS_GetOwnPropertyDescriptor. Migrate a test from JS_GetPropertyAttributes to the new thing. r=njn. --HG-- extra : rebase_source : 0141c90cc8c75b223e09c9125f6daef9f704082e --- .../testDefineGetterSetterNonEnumerable.cpp | 15 ++++--- js/src/jsapi.cpp | 42 +++++++++++++------ js/src/jsapi.h | 15 +++++-- js/src/vm/ScopeObject.cpp | 2 +- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp index 5eb03811264e..94e684c584f0 100644 --- a/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp +++ b/js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp @@ -45,14 +45,13 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable) JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, (JSObject*) funSetObj), JSPROP_GETTER | JSPROP_SETTER | JSPROP_PERMANENT)); - bool found = false; - unsigned attrs = 0; - CHECK(JS_GetPropertyAttributes(cx, vObject, PROPERTY_NAME, &attrs, &found)); - CHECK(found); - CHECK(attrs & JSPROP_GETTER); - CHECK(attrs & JSPROP_SETTER); - CHECK(attrs & JSPROP_PERMANENT); - CHECK(!(attrs & JSPROP_ENUMERATE)); + JS::Rooted desc(cx); + CHECK(JS_GetOwnPropertyDescriptor(cx, vObject, PROPERTY_NAME, 0, &desc)); + CHECK(desc.object()); + CHECK(desc.hasGetterObject()); + CHECK(desc.hasSetterObject()); + CHECK(desc.isPermanent()); + CHECK(!desc.isEnumerable()); return true; } diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index bc002d441360..e16141ff804b 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3633,6 +3633,27 @@ GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id, unsigned return true; } +JS_PUBLIC_API(bool) +JS_GetOwnPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsigned flags, + MutableHandle desc) +{ + RootedObject obj(cx, objArg); + RootedId id(cx, idArg); + AssertHeapIsIdle(cx); + CHECK_REQUEST(cx); + + return GetPropertyDescriptorById(cx, obj, id, flags, true, desc); +} + +JS_PUBLIC_API(bool) +JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags, + MutableHandle desc) +{ + RootedObject obj(cx, objArg); + JSAtom *atom = Atomize(cx, name, strlen(name)); + return atom && JS_GetOwnPropertyDescriptorById(cx, obj, AtomToId(atom), flags, desc); +} + JS_PUBLIC_API(bool) JS_GetPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsigned flags, MutableHandle desc) @@ -3642,6 +3663,15 @@ JS_GetPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid idArg, unsign return GetPropertyDescriptorById(cx, obj, id, flags, false, desc); } +JS_PUBLIC_API(bool) +JS_GetPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags, + MutableHandle desc) +{ + RootedObject obj(cx, objArg); + JSAtom *atom = Atomize(cx, name, strlen(name)); + return atom && JS_GetPropertyDescriptorById(cx, obj, AtomToId(atom), flags, desc); +} + JS_PUBLIC_API(bool) JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *objArg, jsid idArg, unsigned *attrsp, bool *foundp, @@ -3705,17 +3735,6 @@ JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *objArg, attrsp, foundp, getterp, setterp); } -JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, jsid idArg, MutableHandleValue vp) -{ - RootedObject obj(cx, objArg); - RootedId id(cx, idArg); - AssertHeapIsIdle(cx); - CHECK_REQUEST(cx); - - return GetOwnPropertyDescriptor(cx, obj, id, vp); -} - static bool SetPropertyAttributesById(JSContext *cx, HandleObject obj, HandleId id, unsigned attrs, bool *foundp) { @@ -6664,4 +6683,3 @@ JS_PreventExtensions(JSContext *cx, JS::HandleObject obj) return true; return JSObject::preventExtensions(cx, obj); } - diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 4bcdeb81ed96..9dee6d80a5a8 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3013,9 +3013,17 @@ class MutableHandleBase } /* namespace js */ +extern JS_PUBLIC_API(bool) +JS_GetOwnPropertyDescriptorById(JSContext *cx, JSObject *objArg, jsid id, unsigned flags, + JS::MutableHandle desc); + +extern JS_PUBLIC_API(bool) +JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsigned flags, + JS::MutableHandle desc); + /* - * Like JS_GetPropertyAttrsGetterAndSetterById but will return a property on - * an object on the prototype chain (returned in objp). If data->obj is null, + * Like JS_GetOwnPropertyDescriptorById but will return a property on + * an object on the prototype chain (returned in desc->obj). If desc->obj is null, * then this property was not found on the prototype chain. */ extern JS_PUBLIC_API(bool) @@ -3023,7 +3031,8 @@ JS_GetPropertyDescriptorById(JSContext *cx, JSObject *obj, jsid id, unsigned fla JS::MutableHandle desc); extern JS_PUBLIC_API(bool) -JS_GetOwnPropertyDescriptor(JSContext *cx, JSObject *obj, jsid id, JS::MutableHandle vp); +JS_GetPropertyDescriptor(JSContext *cx, JSObject *obj, const char *name, unsigned flags, + JS::MutableHandle desc); extern JS_PUBLIC_API(bool) JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, JS::MutableHandle vp); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index df9e494262b5..98133009046f 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1408,7 +1408,7 @@ class DebugScopeProxy : public BaseProxyHandler return true; } - return JS_GetPropertyDescriptorById(cx, scope, id, 0, desc); + return JS_GetOwnPropertyDescriptorById(cx, scope, id, flags, desc); } bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, From 7e763809ebec3401741251e4f6bd0625c59651c3 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 6 Sep 2013 12:05:30 -0500 Subject: [PATCH 05/36] Bug 893186, part 4 - Replace a use of JS_GetUCPropertyAttributes in JSD with a call to JS_GetOwnPropertyDescriptorById. r=luke. --HG-- extra : rebase_source : 4b035be0aec9206c3849c45ade6b88718a15031b --- js/jsd/jsd_val.cpp | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/js/jsd/jsd_val.cpp b/js/jsd/jsd_val.cpp index 44618a11bc1f..007327cb153e 100644 --- a/js/jsd/jsd_val.cpp +++ b/js/jsd/jsd_val.cpp @@ -477,10 +477,7 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr) JSDProperty* jsdprop; JSDProperty* iter = NULL; JS::RootedObject obj(cx); - unsigned attrs = 0; bool found; - const jschar * nameChars; - size_t nameLen; JS::RootedValue val(cx), nameval(cx); JS::RootedId nameid(cx); JS::RootedValue propId(cx); @@ -504,24 +501,28 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr) } /* Not found in property list, look it up explicitly */ + nameval = STRING_TO_JSVAL(name); + if(!JS_ValueToId(cx, nameval, nameid.address())) + return NULL; + if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; - if (!(nameChars = JS_GetStringCharsZAndLength(cx, name, &nameLen))) - return NULL; - + JS::Rooted desc(cx); { JSAutoCompartment ac(cx, obj); + JS::RootedId id(cx, nameid); - JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found); - if (!found) - { + if(!JS_WrapId(cx, id.address())) + return NULL; + if(!JS_GetOwnPropertyDescriptorById(cx, obj, id, 0, &desc)) + return NULL; + if(!desc.object()) return NULL; - } JS_ClearPendingException(cx); - if(!JS_GetUCProperty(cx, obj, nameChars, nameLen, &val)) + if(!JS_GetPropertyById(cx, obj, id, &val)) { if (JS_IsExceptionPending(cx)) { @@ -543,16 +544,13 @@ jsd_GetValueProperty(JSDContext* jsdc, JSDValue* jsdval, JSString* nameStr) } } - nameval = STRING_TO_JSVAL(name); - if (!JS_ValueToId(cx, nameval, nameid.address()) || - !JS_IdToValue(cx, nameid, propId.address())) { + if (!JS_IdToValue(cx, nameid, propId.address())) return NULL; - } propAlias = JSVAL_NULL; - propFlags |= (attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0 - | (attrs & JSPROP_READONLY) ? JSPD_READONLY : 0 - | (attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0; + propFlags |= desc.isEnumerable() ? JSPD_ENUMERATE : 0 + | desc.isReadonly() ? JSPD_READONLY : 0 + | desc.isPermanent() ? JSPD_PERMANENT : 0; return _newProperty(jsdc, propId, propValue, propAlias, propFlags, JSDPD_HINTED); } From badbd7be37af43b095e534784c3f39a85320a0f5 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 6 Sep 2013 12:05:30 -0500 Subject: [PATCH 06/36] Bug 893186, part 5 - Delete JS_GetPropertyAttributes and many similar APIs; remove half a dozen methods from JS::Class. r=Waldo. --HG-- extra : rebase_source : 1f4a01938b06b66ef855f9b654f098b4819b1390 --- js/public/Class.h | 13 +-- js/src/builtin/TypedObject.cpp | 60 ----------- js/src/builtin/TypedObject.h | 13 --- js/src/jsapi.cpp | 103 ------------------- js/src/jsapi.h | 74 -------------- js/src/jsobj.cpp | 38 ------- js/src/jsobj.h | 29 ------ js/src/jsobjinlines.h | 34 ------- js/src/jsproxy.cpp | 64 ------------ js/src/vm/ScopeObject.cpp | 48 --------- js/src/vm/TypedArrayObject.cpp | 112 --------------------- js/src/vm/TypedArrayObject.h | 26 ----- js/xpconnect/src/XPCWrappedNativeJSOps.cpp | 6 -- js/xpconnect/src/xpcprivate.h | 12 --- 14 files changed, 1 insertion(+), 631 deletions(-) diff --git a/js/public/Class.h b/js/public/Class.h index 08f72b0a3f80..cb0dfce040f7 100644 --- a/js/public/Class.h +++ b/js/public/Class.h @@ -373,10 +373,6 @@ typedef bool (* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, unsigned *attrsp); typedef bool -(* ElementAttributesOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, unsigned *attrsp); -typedef bool -(* SpecialAttributesOp)(JSContext *cx, JS::HandleObject obj, HandleSpecialId sid, unsigned *attrsp); -typedef bool (* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle name, bool *succeeded); typedef bool @@ -468,13 +464,7 @@ struct ObjectOps StrictElementIdOp setElement; StrictSpecialIdOp setSpecial; GenericAttributesOp getGenericAttributes; - PropertyAttributesOp getPropertyAttributes; - ElementAttributesOp getElementAttributes; - SpecialAttributesOp getSpecialAttributes; GenericAttributesOp setGenericAttributes; - PropertyAttributesOp setPropertyAttributes; - ElementAttributesOp setElementAttributes; - SpecialAttributesOp setSpecialAttributes; DeletePropertyOp deleteProperty; DeleteElementOp deleteElement; DeleteSpecialOp deleteSpecial; @@ -485,8 +475,7 @@ struct ObjectOps #define JS_NULL_OBJECT_OPS \ {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ - NULL,NULL,NULL} + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL} } // namespace js diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 26ac3f22833f..ae386e9010e1 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -1664,13 +1664,7 @@ Class BinaryBlock::class_ = { BinaryBlock::obj_setElement, BinaryBlock::obj_setSpecial, BinaryBlock::obj_getGenericAttributes, - BinaryBlock::obj_getPropertyAttributes, - BinaryBlock::obj_getElementAttributes, - BinaryBlock::obj_getSpecialAttributes, BinaryBlock::obj_setGenericAttributes, - BinaryBlock::obj_setPropertyAttributes, - BinaryBlock::obj_setElementAttributes, - BinaryBlock::obj_setSpecialAttributes, BinaryBlock::obj_deleteProperty, BinaryBlock::obj_deleteElement, BinaryBlock::obj_deleteSpecial, @@ -2204,33 +2198,6 @@ BinaryBlock::obj_getGenericAttributes(JSContext *cx, HandleObject obj, return JSObject::getGenericAttributes(cx, proto, id, attrsp); } -bool -BinaryBlock::obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, - unsigned *attrsp) -{ - RootedId id(cx, NameToId(name)); - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - -bool -BinaryBlock::obj_getElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - RootedId id(cx); - if (!IndexToId(cx, index, &id)) - return false; - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - -bool -BinaryBlock::obj_getSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp) -{ - RootedId id(cx, SPECIALID_TO_JSID(sid)); - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - static bool IsOwnId(JSContext *cx, HandleObject obj, HandleId id) { @@ -2270,33 +2237,6 @@ BinaryBlock::obj_setGenericAttributes(JSContext *cx, HandleObject obj, return JSObject::setGenericAttributes(cx, proto, id, attrsp); } -bool -BinaryBlock::obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, - unsigned *attrsp) -{ - RootedId id(cx, NameToId(name)); - return obj_setGenericAttributes(cx, obj, id, attrsp); -} - -bool -BinaryBlock::obj_setElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - RootedId id(cx); - if (!IndexToId(cx, index, &id)) - return false; - return obj_setGenericAttributes(cx, obj, id, attrsp); -} - -bool -BinaryBlock::obj_setSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp) -{ - RootedId id(cx, SPECIALID_TO_JSID(sid)); - return obj_setGenericAttributes(cx, obj, id, attrsp); -} - bool BinaryBlock::obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded) diff --git a/js/src/builtin/TypedObject.h b/js/src/builtin/TypedObject.h index fc842f6a784e..0e3c3a282c98 100644 --- a/js/src/builtin/TypedObject.h +++ b/js/src/builtin/TypedObject.h @@ -181,21 +181,8 @@ class BinaryBlock static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_getElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); - static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_setElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e16141ff804b..b18d66f28ee3 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3672,109 +3672,6 @@ JS_GetPropertyDescriptor(JSContext *cx, JSObject *objArg, const char *name, unsi return atom && JS_GetPropertyDescriptorById(cx, obj, AtomToId(atom), flags, desc); } -JS_PUBLIC_API(bool) -JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *objArg, jsid idArg, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, JSStrictPropertyOp *setterp) -{ - RootedObject obj(cx, objArg); - RootedId id(cx, idArg); - Rooted desc(cx); - if (!GetPropertyDescriptorById(cx, obj, id, 0, false, &desc)) - return false; - - *attrsp = desc.attributes(); - *foundp = !!desc.object(); - if (getterp) - *getterp = desc.getter(); - if (setterp) - *setterp = desc.setter(); - return true; -} - -JS_PUBLIC_API(bool) -JS_GetPropertyAttributes(JSContext *cx, JSObject *objArg, const char *name, - unsigned *attrsp, bool *foundp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = Atomize(cx, name, strlen(name)); - return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom), - attrsp, foundp, NULL, NULL); -} - -JS_PUBLIC_API(bool) -JS_GetUCPropertyAttributes(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen, - unsigned *attrsp, bool *foundp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); - return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom), - attrsp, foundp, NULL, NULL); -} - -JS_PUBLIC_API(bool) -JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *objArg, const char *name, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, JSStrictPropertyOp *setterp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = Atomize(cx, name, strlen(name)); - return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom), - attrsp, foundp, getterp, setterp); -} - -JS_PUBLIC_API(bool) -JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *objArg, - const jschar *name, size_t namelen, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, JSStrictPropertyOp *setterp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); - return atom && JS_GetPropertyAttrsGetterAndSetterById(cx, obj, AtomToId(atom), - attrsp, foundp, getterp, setterp); -} - -static bool -SetPropertyAttributesById(JSContext *cx, HandleObject obj, HandleId id, unsigned attrs, bool *foundp) -{ - RootedObject obj2(cx); - RootedShape shape(cx); - - if (!LookupPropertyById(cx, obj, id, 0, &obj2, &shape)) - return false; - if (!shape || obj != obj2) { - *foundp = false; - return true; - } - bool ok = obj->isNative() - ? JSObject::changePropertyAttributes(cx, obj, shape, attrs) - : JSObject::setGenericAttributes(cx, obj, id, &attrs); - if (ok) - *foundp = true; - return ok; -} - -JS_PUBLIC_API(bool) -JS_SetPropertyAttributes(JSContext *cx, JSObject *objArg, const char *name, - unsigned attrs, bool *foundp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = Atomize(cx, name, strlen(name)); - RootedId id(cx, AtomToId(atom)); - return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp); -} - -JS_PUBLIC_API(bool) -JS_SetUCPropertyAttributes(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen, - unsigned attrs, bool *foundp) -{ - RootedObject obj(cx, objArg); - JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); - RootedId id(cx, AtomToId(atom)); - return atom && SetPropertyAttributesById(cx, obj, id, attrs, foundp); -} - JS_PUBLIC_API(bool) JS_GetPropertyById(JSContext *cx, JSObject *objArg, jsid idArg, MutableHandleValue vp) { diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 9dee6d80a5a8..80d5b0031ad7 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2791,45 +2791,6 @@ JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value, extern JS_PUBLIC_API(bool) JS_DefineOwnProperty(JSContext *cx, JSObject *obj, jsid id, jsval descriptor, bool *bp); -/* - * Determine the attributes (JSPROP_* flags) of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * false and the value of *attrsp is undefined. - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, - unsigned *attrsp, bool *foundp); - -/* - * The same, but if the property is native, return its getter and setter via - * *getterp and *setterp, respectively (and only if the out parameter pointer - * is not null). - */ -extern JS_PUBLIC_API(bool) -JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, - const char *name, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -extern JS_PUBLIC_API(bool) -JS_GetPropertyAttrsGetterAndSetterById(JSContext *cx, JSObject *obj, - jsid id, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -/* - * Set the attributes of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * false and nothing will be altered. - */ -extern JS_PUBLIC_API(bool) -JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, - unsigned attrs, bool *foundp); - extern JS_PUBLIC_API(bool) JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, int8_t tinyid, jsval value, @@ -3076,41 +3037,6 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj, JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs); -/* - * Determine the attributes (JSPROP_* flags) of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * false and the value of *attrsp is undefined. - */ -extern JS_PUBLIC_API(bool) -JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - unsigned *attrsp, bool *foundp); - -/* - * The same, but if the property is native, return its getter and setter via - * *getterp and *setterp, respectively (and only if the out parameter pointer - * is not null). - */ -extern JS_PUBLIC_API(bool) -JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - unsigned *attrsp, bool *foundp, - JSPropertyOp *getterp, - JSStrictPropertyOp *setterp); - -/* - * Set the attributes of a property on a given object. - * - * If the object does not have a property by that name, *foundp will be - * false and nothing will be altered. - */ -extern JS_PUBLIC_API(bool) -JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, - const jschar *name, size_t namelen, - unsigned attrs, bool *foundp); - - extern JS_PUBLIC_API(bool) JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 89a1333dc667..548d0bceab12 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4775,24 +4775,6 @@ baseops::GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a return true; } -bool -baseops::GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedObject nobj(cx); - RootedShape shape(cx); - if (!baseops::LookupElement(cx, obj, index, &nobj, &shape)) - return false; - if (!shape) { - *attrsp = 0; - return true; - } - if (!nobj->isNative()) - return JSObject::getElementAttributes(cx, nobj, index, attrsp); - - *attrsp = GetShapeAttributes(shape); - return true; -} - bool baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp) { @@ -4812,26 +4794,6 @@ baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a : JSObject::setGenericAttributes(cx, nobj, id, attrsp); } -bool -baseops::SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedObject nobj(cx); - RootedShape shape(cx); - if (!baseops::LookupElement(cx, obj, index, &nobj, &shape)) - return false; - if (!shape) - return true; - if (nobj->isNative() && IsImplicitDenseElement(shape)) { - if (!JSObject::sparsifyDenseElement(cx, obj, index)) - return false; - jsid id = INT_TO_JSID(index); - shape = obj->nativeLookup(cx, HandleId::fromMarkedLocation(&id)); // not a gcthing - } - return nobj->isNative() - ? JSObject::changePropertyAttributes(cx, nobj, shape, *attrsp) - : JSObject::setElementAttributes(cx, nobj, index, attrsp); -} - bool baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 76de4ec7a56c..396b2d1caa29 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -143,12 +143,6 @@ GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); extern bool SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); -extern bool -GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp); - -extern bool -SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp); - extern bool DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded); @@ -881,31 +875,8 @@ class JSObject : public js::ObjectImpl return (op ? op : js::baseops::GetAttributes)(cx, obj, id, attrsp); } - static bool getPropertyAttributes(JSContext *cx, js::HandleObject obj, - js::PropertyName *name, unsigned *attrsp) - { - JS::RootedId id(cx, js::NameToId(name)); - return getGenericAttributes(cx, obj, id, attrsp); - } - - static inline bool getElementAttributes(JSContext *cx, js::HandleObject obj, - uint32_t index, unsigned *attrsp); - - static bool getSpecialAttributes(JSContext *cx, js::HandleObject obj, - js::SpecialId sid, unsigned *attrsp) - { - JS::RootedId id(cx, SPECIALID_TO_JSID(sid)); - return getGenericAttributes(cx, obj, id, attrsp); - } - static inline bool setGenericAttributes(JSContext *cx, js::HandleObject obj, js::HandleId id, unsigned *attrsp); - static inline bool setPropertyAttributes(JSContext *cx, js::HandleObject obj, - js::PropertyName *name, unsigned *attrsp); - static inline bool setElementAttributes(JSContext *cx, js::HandleObject obj, - uint32_t index, unsigned *attrsp); - static inline bool setSpecialAttributes(JSContext *cx, js::HandleObject obj, - js::SpecialId sid, unsigned *attrsp); static inline bool deleteProperty(JSContext *cx, js::HandleObject obj, js::HandlePropertyName name, diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index b0ff58f21f65..970ae60e8d93 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -31,30 +31,6 @@ JSObject::setGenericAttributes(JSContext *cx, js::HandleObject obj, return (op ? op : js::baseops::SetAttributes)(cx, obj, id, attrsp); } -/* static */ inline bool -JSObject::setPropertyAttributes(JSContext *cx, js::HandleObject obj, - js::PropertyName *name, unsigned *attrsp) -{ - JS::RootedId id(cx, js::NameToId(name)); - return setGenericAttributes(cx, obj, id, attrsp); -} - -/* static */ inline bool -JSObject::setElementAttributes(JSContext *cx, js::HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - js::ElementAttributesOp op = obj->getOps()->setElementAttributes; - return (op ? op : js::baseops::SetElementAttributes)(cx, obj, index, attrsp); -} - -/* static */ inline bool -JSObject::setSpecialAttributes(JSContext *cx, js::HandleObject obj, - js::SpecialId sid, unsigned *attrsp) -{ - JS::RootedId id(cx, SPECIALID_TO_JSID(sid)); - return setGenericAttributes(cx, obj, id, attrsp); -} - /* static */ inline bool JSObject::changePropertyAttributes(JSContext *cx, js::HandleObject obj, js::HandleShape shape, unsigned attrs) @@ -747,16 +723,6 @@ JSObject::getElementIfPresent(JSContext *cx, js::HandleObject obj, js::HandleObj return getGeneric(cx, obj, receiver, id, vp); } -/* static */ inline bool -JSObject::getElementAttributes(JSContext *cx, js::HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - JS::RootedId id(cx); - if (!js::IndexToId(cx, index, &id)) - return false; - return getGenericAttributes(cx, obj, id, attrsp); -} - inline js::GlobalObject & JSObject::global() const { diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 70904010d3b6..898b65e1aa12 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -2892,29 +2892,6 @@ proxy_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigne return true; } -static bool -proxy_GetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp) -{ - Rooted id(cx, NameToId(name)); - return proxy_GetGenericAttributes(cx, obj, id, attrsp); -} - -static bool -proxy_GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedId id(cx); - if (!IndexToId(cx, index, &id)) - return false; - return proxy_GetGenericAttributes(cx, obj, id, attrsp); -} - -static bool -proxy_GetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp) -{ - Rooted id(cx, SPECIALID_TO_JSID(sid)); - return proxy_GetGenericAttributes(cx, obj, id, attrsp); -} - static bool proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp) { @@ -2926,29 +2903,6 @@ proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigne return Proxy::defineProperty(cx, obj, id, &desc); } -static bool -proxy_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp) -{ - Rooted id(cx, NameToId(name)); - return proxy_SetGenericAttributes(cx, obj, id, attrsp); -} - -static bool -proxy_SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedId id(cx); - if (!IndexToId(cx, index, &id)) - return false; - return proxy_SetGenericAttributes(cx, obj, id, attrsp); -} - -static bool -proxy_SetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp) -{ - Rooted id(cx, SPECIALID_TO_JSID(sid)); - return proxy_SetGenericAttributes(cx, obj, id, attrsp); -} - static bool proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded) { @@ -3103,13 +3057,7 @@ Class js::ObjectProxyObject::class_ = { proxy_SetElement, proxy_SetSpecial, proxy_GetGenericAttributes, - proxy_GetPropertyAttributes, - proxy_GetElementAttributes, - proxy_GetSpecialAttributes, proxy_SetGenericAttributes, - proxy_SetPropertyAttributes, - proxy_SetElementAttributes, - proxy_SetSpecialAttributes, proxy_DeleteProperty, proxy_DeleteElement, proxy_DeleteSpecial, @@ -3162,13 +3110,7 @@ Class js::OuterWindowProxyObject::class_ = { proxy_SetElement, proxy_SetSpecial, proxy_GetGenericAttributes, - proxy_GetPropertyAttributes, - proxy_GetElementAttributes, - proxy_GetSpecialAttributes, proxy_SetGenericAttributes, - proxy_SetPropertyAttributes, - proxy_SetElementAttributes, - proxy_SetSpecialAttributes, proxy_DeleteProperty, proxy_DeleteElement, proxy_DeleteSpecial, @@ -3233,13 +3175,7 @@ Class js::FunctionProxyObject::class_ = { proxy_SetElement, proxy_SetSpecial, proxy_GetGenericAttributes, - proxy_GetPropertyAttributes, - proxy_GetElementAttributes, - proxy_GetSpecialAttributes, proxy_SetGenericAttributes, - proxy_SetPropertyAttributes, - proxy_SetElementAttributes, - proxy_SetSpecialAttributes, proxy_DeleteProperty, proxy_DeleteElement, proxy_DeleteSpecial, diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 98133009046f..61c09c5bcc68 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -511,27 +511,6 @@ with_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned return JSObject::getGenericAttributes(cx, actual, id, attrsp); } -static bool -with_GetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::getPropertyAttributes(cx, actual, name, attrsp); -} - -static bool -with_GetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::getElementAttributes(cx, actual, index, attrsp); -} - -static bool -with_GetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::getSpecialAttributes(cx, actual, sid, attrsp); -} - static bool with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp) { @@ -539,27 +518,6 @@ with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned return JSObject::setGenericAttributes(cx, actual, id, attrsp); } -static bool -with_SetPropertyAttributes(JSContext *cx, HandleObject obj, HandlePropertyName name, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::setPropertyAttributes(cx, actual, name, attrsp); -} - -static bool -with_SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::setElementAttributes(cx, actual, index, attrsp); -} - -static bool -with_SetSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, unsigned *attrsp) -{ - RootedObject actual(cx, &obj->as().object()); - return JSObject::setSpecialAttributes(cx, actual, sid, attrsp); -} - static bool with_DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded) @@ -635,13 +593,7 @@ Class WithObject::class_ = { with_SetElement, with_SetSpecial, with_GetGenericAttributes, - with_GetPropertyAttributes, - with_GetElementAttributes, - with_GetSpecialAttributes, with_SetGenericAttributes, - with_SetPropertyAttributes, - with_SetElementAttributes, - with_SetSpecialAttributes, with_DeleteProperty, with_DeleteElement, with_DeleteSpecial, diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 7067d2268ec2..ff7f2b26e3b2 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1020,32 +1020,6 @@ ArrayBufferObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj, return baseops::GetAttributes(cx, delegate, id, attrsp); } -bool -ArrayBufferObject::obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp) -{ - Rooted id(cx, NameToId(name)); - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - -bool -ArrayBufferObject::obj_getElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - RootedObject delegate(cx, ArrayBufferDelegate(cx, obj)); - if (!delegate) - return false; - return baseops::GetElementAttributes(cx, delegate, index, attrsp); -} - -bool -ArrayBufferObject::obj_getSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp) -{ - Rooted id(cx, SPECIALID_TO_JSID(sid)); - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - bool ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp) @@ -1056,32 +1030,6 @@ ArrayBufferObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, return baseops::SetAttributes(cx, delegate, id, attrsp); } -bool -ArrayBufferObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp) -{ - Rooted id(cx, NameToId(name)); - return obj_setGenericAttributes(cx, obj, id, attrsp); -} - -bool -ArrayBufferObject::obj_setElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp) -{ - RootedObject delegate(cx, ArrayBufferDelegate(cx, obj)); - if (!delegate) - return false; - return baseops::SetElementAttributes(cx, delegate, index, attrsp); -} - -bool -ArrayBufferObject::obj_setSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp) -{ - Rooted id(cx, SPECIALID_TO_JSID(sid)); - return obj_setGenericAttributes(cx, obj, id, attrsp); -} - bool ArrayBufferObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded) @@ -1231,30 +1179,6 @@ TypedArrayObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj, Hand return true; } -bool -TypedArrayObject::obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp) -{ - *attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE; - return true; -} - -bool -TypedArrayObject::obj_getElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, - unsigned *attrsp) -{ - *attrsp = JSPROP_PERMANENT | JSPROP_ENUMERATE; - return true; -} - -bool -TypedArrayObject::obj_getSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, - unsigned *attrsp) -{ - Rooted id(cx, SPECIALID_TO_JSID(sid)); - return obj_getGenericAttributes(cx, obj, id, attrsp); -} - bool TypedArrayObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp) @@ -1263,30 +1187,6 @@ TypedArrayObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj, Hand return false; } -bool -TypedArrayObject::obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp) -{ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS); - return false; -} - -bool -TypedArrayObject::obj_setElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, - unsigned *attrsp) -{ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS); - return false; -} - -bool -TypedArrayObject::obj_setSpecialAttributes(JSContext *cx, HandleObject obj, HandleSpecialId sid, - unsigned *attrsp) -{ - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS); - return false; -} - /* static */ int TypedArrayObject::lengthOffset() { @@ -3494,13 +3394,7 @@ Class ArrayBufferObject::class_ = { ArrayBufferObject::obj_setElement, ArrayBufferObject::obj_setSpecial, ArrayBufferObject::obj_getGenericAttributes, - ArrayBufferObject::obj_getPropertyAttributes, - ArrayBufferObject::obj_getElementAttributes, - ArrayBufferObject::obj_getSpecialAttributes, ArrayBufferObject::obj_setGenericAttributes, - ArrayBufferObject::obj_setPropertyAttributes, - ArrayBufferObject::obj_setElementAttributes, - ArrayBufferObject::obj_setSpecialAttributes, ArrayBufferObject::obj_deleteProperty, ArrayBufferObject::obj_deleteElement, ArrayBufferObject::obj_deleteSpecial, @@ -3662,13 +3556,7 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Float64, double, double) _typedArray##Object::obj_setElement, \ _typedArray##Object::obj_setSpecial, \ _typedArray##Object::obj_getGenericAttributes, \ - _typedArray##Object::obj_getPropertyAttributes, \ - _typedArray##Object::obj_getElementAttributes, \ - _typedArray##Object::obj_getSpecialAttributes, \ _typedArray##Object::obj_setGenericAttributes, \ - _typedArray##Object::obj_setPropertyAttributes, \ - _typedArray##Object::obj_setElementAttributes, \ - _typedArray##Object::obj_setSpecialAttributes, \ _typedArray##Object::obj_deleteProperty, \ _typedArray##Object::obj_deleteElement, \ _typedArray##Object::obj_deleteSpecial, \ diff --git a/js/src/vm/TypedArrayObject.h b/js/src/vm/TypedArrayObject.h index 1f9c122ea029..e757c0a950d5 100644 --- a/js/src/vm/TypedArrayObject.h +++ b/js/src/vm/TypedArrayObject.h @@ -124,21 +124,8 @@ class ArrayBufferObject : public JSObject static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_getElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); - static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_setElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded); @@ -295,21 +282,8 @@ class TypedArrayObject : public ArrayBufferViewObject static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_getPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_getElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_getSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); - static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); - static bool obj_setPropertyAttributes(JSContext *cx, HandleObject obj, - HandlePropertyName name, unsigned *attrsp); - static bool obj_setElementAttributes(JSContext *cx, HandleObject obj, - uint32_t index, unsigned *attrsp); - static bool obj_setSpecialAttributes(JSContext *cx, HandleObject obj, - HandleSpecialId sid, unsigned *attrsp); static Value bufferValue(TypedArrayObject *tarr) { return tarr->getFixedSlot(BUFFER_SLOT); diff --git a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp index 4c042a78af88..2c949f5ea770 100644 --- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp +++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp @@ -735,13 +735,7 @@ XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = { nullptr, // setElement nullptr, // setSpecial nullptr, // getGenericAttributes - nullptr, // getAttributes - nullptr, // getElementAttributes - nullptr, // getSpecialAttributes nullptr, // setGenericAttributes - nullptr, // setAttributes - nullptr, // setElementAttributes - nullptr, // setSpecialAttributes nullptr, // deleteProperty nullptr, // deleteElement nullptr, // deleteSpecial diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index ee4a2ef7c242..0558a0806b95 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -1203,13 +1203,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj); nullptr, /* setElement */ \ nullptr, /* setSpecial */ \ nullptr, /* getGenericAttributes */ \ - nullptr, /* getAttributes */ \ - nullptr, /* getElementAttributes */ \ - nullptr, /* getSpecialAttributes */ \ nullptr, /* setGenericAttributes */ \ - nullptr, /* setAttributes */ \ - nullptr, /* setElementAttributes */ \ - nullptr, /* setSpecialAttributes */ \ nullptr, /* deleteProperty */ \ nullptr, /* deleteElement */ \ nullptr, /* deleteSpecial */ \ @@ -1237,13 +1231,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj); nullptr, /* setElement */ \ nullptr, /* setSpecial */ \ nullptr, /* getGenericAttributes */ \ - nullptr, /* getAttributes */ \ - nullptr, /* getElementAttributes */ \ - nullptr, /* getSpecialAttributes */ \ nullptr, /* setGenericAttributes */ \ - nullptr, /* setAttributes */ \ - nullptr, /* setElementAttributes */ \ - nullptr, /* setSpecialAttributes */ \ nullptr, /* deleteProperty */ \ nullptr, /* deleteElement */ \ nullptr, /* deleteSpecial */ \ From 0f4ca5e1013001703f78eb71f7997abbc7e00799 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Thu, 5 Sep 2013 11:57:18 -0700 Subject: [PATCH 07/36] Bug 912748 - Only call GsmCellLocation.getPsc() on GB+. r=blassey --- mobile/android/base/GeckoApp.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index 22f75c107105..82dcf37eb778 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -2347,7 +2347,10 @@ abstract public class GeckoApp try { obj.put("lac", gcl.getLac()); obj.put("cid", gcl.getCid()); - obj.put("psc", gcl.getPsc()); + + int psc = (Build.VERSION.SDK_INT >= 9) ? gcl.getPsc() : -1; + obj.put("psc", psc); + switch(tm.getNetworkType()) { case TelephonyManager.NETWORK_TYPE_GPRS: case TelephonyManager.NETWORK_TYPE_EDGE: From 0ea468eaff6f79b7f8bce2952158a4eb36d7066f Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 6 Sep 2013 10:57:40 -0700 Subject: [PATCH 08/36] Bug 913247 followup: Remove superfluous call to imagesToRefresh.Clear(). rs=bz --- layout/base/nsRefreshDriver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 57dff5d32819..f14c33bcc9f3 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1168,7 +1168,6 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) for (uint32_t i = 0; i < imagesToRefresh.Length(); i++) { imagesToRefresh[i]->RequestRefresh(aNowTime); } - imagesToRefresh.Clear(); } for (uint32_t i = 0; i < mPresShellsToInvalidateIfHidden.Length(); i++) { From 8190b016ebaa4de7b2f20e13aca4aac84c188cae Mon Sep 17 00:00:00 2001 From: Kannan Vijayan Date: Fri, 6 Sep 2013 14:27:07 -0400 Subject: [PATCH 09/36] Bug 909764 - Fix IonBuilder to properly propagate exceptions raised during compilation. Make getTypeOrSingleObject (and any of its infallible callers) into fallible methods. r=h4writer --- js/src/jit/Ion.cpp | 8 ++ js/src/jit/Ion.h | 1 + js/src/jit/IonBuilder.cpp | 84 +++++++++++++++--- js/src/jit/MCallOptimize.cpp | 29 ++++-- js/src/jit/MIR.cpp | 168 ++++++++++++++++++++++++----------- js/src/jit/MIR.h | 12 +-- js/src/jsinfer.h | 2 +- js/src/jsinferinlines.h | 18 ++-- 8 files changed, 242 insertions(+), 80 deletions(-) diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index c765ea322946..7a28ba142867 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -1652,6 +1652,11 @@ IonCompile(JSContext *cx, JSScript *script, IonSpewNewFunction(graph, builderScript); if (!builder->build()) { + if (cx->isExceptionPending()) { + IonSpew(IonSpew_Abort, "Builder raised exception."); + return AbortReason_Error; + } + IonSpew(IonSpew_Abort, "Builder failed to build."); return builder->abortReason(); } @@ -1832,6 +1837,9 @@ Compile(JSContext *cx, HandleScript script, BaselineFrame *osrFrame, jsbytecode } AbortReason reason = IonCompile(cx, script, osrFrame, osrPc, constructing, executionMode); + if (reason == AbortReason_Error) + return Method_Error; + if (reason == AbortReason_Disable) return Method_CantCompile; diff --git a/js/src/jit/Ion.h b/js/src/jit/Ion.h index 05db5cb864c4..5d895d1b6a70 100644 --- a/js/src/jit/Ion.h +++ b/js/src/jit/Ion.h @@ -255,6 +255,7 @@ enum AbortReason { AbortReason_Alloc, AbortReason_Inlining, AbortReason_Disable, + AbortReason_Error, AbortReason_NoAbort }; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index f4bf7b224b2a..602eb897819e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -3772,14 +3772,23 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target) AutoAccumulateExits aae(graph(), saveExits); // Build the graph. + JS_ASSERT(!cx->isExceptionPending()); IonBuilder inlineBuilder(cx, &temp(), &graph(), &inspector, info, NULL, inliningDepth_ + 1, loopDepth_); if (!inlineBuilder.buildInline(this, outerResumePoint, callInfo)) { JS_ASSERT(calleeScript->hasAnalysis()); + if (cx->isExceptionPending()) { + IonSpew(IonSpew_Abort, "Inline builder raised exception."); + abortReason_ = AbortReason_Error; + return false; + } // Inlining the callee failed. Disable inlining the function - if (inlineBuilder.abortReason_ == AbortReason_Disable) + if (inlineBuilder.abortReason_ == AbortReason_Disable) { + // Only mark callee as un-inlineable only if the inlining was aborted + // for a non-exception reason. calleeScript->analysis()->setIonUninlineable(); + } abortReason_ = AbortReason_Inlining; return false; @@ -5565,9 +5574,20 @@ IonBuilder::jsop_initprop(HandlePropertyName name) if (!res) return false; - if (!shape || holder != templateObject || - PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value)) + if (!shape || holder != templateObject) { + // JSOP_NEWINIT becomes an MNewObject without preconfigured properties. + MInitProp *init = MInitProp::New(obj, name, value); + current->add(init); + return resumeAfter(init); + } + + bool writeNeedsBarrier = false; + if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value, /* canModify = */ true, + &writeNeedsBarrier)) { + return false; + } + if (writeNeedsBarrier) { // JSOP_NEWINIT becomes an MNewObject without preconfigured properties. MInitProp *init = MInitProp::New(obj, name, value); current->add(init); @@ -6267,7 +6287,12 @@ IonBuilder::getStaticName(HandleObject staticObject, HandlePropertyName name, bo } types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc); - bool barrier = PropertyReadNeedsTypeBarrier(cx, staticType, name, types); + bool barrier; + if (!PropertyReadNeedsTypeBarrier(cx, staticType, name, types, /* updateObserved = */ true, + &barrier)) + { + return false; + } // If the property is permanent, a shape guard isn't necessary. @@ -6791,7 +6816,9 @@ IonBuilder::getElemTryCache(bool *emitted, MDefinition *obj, MDefinition *index) // Emit GetElementCache. types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc); - bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types); + bool barrier; + if (!PropertyReadNeedsTypeBarrier(cx, obj, NULL, types, &barrier)) + return false; // Always add a barrier if the index might be a string, so that the cache // can attach stubs for particular properties. @@ -6835,10 +6862,14 @@ IonBuilder::jsop_getelem_dense(MDefinition *obj, MDefinition *index) // Indexed call on an element of an array. Populate the observed types // with any objects that could be in the array, to avoid extraneous // type barriers. - AddObjectsForPropertyRead(cx, obj, NULL, types); + if (!AddObjectsForPropertyRead(cx, obj, NULL, types)) + return false; } - bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types); + bool barrier; + if (!PropertyReadNeedsTypeBarrier(cx, obj, NULL, types, &barrier)) + return false; + bool needsHoleCheck = !ElementAccessIsPacked(cx, obj); // Reads which are on holes in the object do not have to bail out if @@ -7203,7 +7234,13 @@ IonBuilder::setElemTryDense(bool *emitted, MDefinition *object, if (!ElementAccessIsDenseNative(object, index)) return true; - if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value)) + bool needsBarrier; + if (!PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value, /* canModify = */ true, + &needsBarrier)) + { + return false; + } + if (needsBarrier) return true; if (!object->resultTypeSet()) return true; @@ -7263,7 +7300,14 @@ IonBuilder::setElemTryCache(bool *emitted, MDefinition *object, if (!icInspect.sawDenseWrite()) return true; - if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value)) + bool needsBarrier; + if (PropertyWriteNeedsTypeBarrier(cx, current, &object, NULL, &value, /* canModify = */ true, + &needsBarrier)) + { + return false; + } + + if (needsBarrier) return true; // Emit SetElementCache. @@ -7283,7 +7327,10 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion, SetElemSafety safety, MDefinition *obj, MDefinition *id, MDefinition *value) { - MIRType elementType = DenseNativeElementType(cx, obj); + MIRType elementType; + if (!DenseNativeElementType(cx, obj, &elementType)) + return false; + bool packed = ElementAccessIsPacked(cx, obj); // Writes which are on holes in the object do not have to bail out if they @@ -8100,7 +8147,9 @@ IonBuilder::jsop_getprop(HandlePropertyName name) if (!getPropTryArgumentsLength(&emitted) || emitted) return emitted; - bool barrier = PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types); + bool barrier; + if (!PropertyReadNeedsTypeBarrier(cx, current->peek(-1), name, types, &barrier)) + return false; // Try to hardcode known constants. if (!getPropTryConstant(&emitted, id, types) || emitted) @@ -8405,7 +8454,11 @@ IonBuilder::getPropTryCache(bool *emitted, HandlePropertyName name, HandleId id, if (obj->type() == MIRType_Object && !invalidatedIdempotentCache() && info().executionMode() != ParallelExecution) { - if (PropertyReadIsIdempotent(cx, obj, name)) + bool idempotent; + if (!PropertyReadIsIdempotent(cx, obj, name, &idempotent)) + return false; + + if (idempotent) load->setIdempotent(); } @@ -8480,7 +8533,12 @@ IonBuilder::jsop_setprop(HandlePropertyName name) return emitted; types::StackTypeSet *objTypes = obj->resultTypeSet(); - bool barrier = PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value); + bool barrier; + if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, name, &value, + /* canModify = */ true, &barrier)) + { + return false; + } // Try to emit store from definite slots. if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 06fe5e5ba942..2584553d4649 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -323,7 +323,10 @@ IonBuilder::inlineArrayPopShift(CallInfo &callInfo, MArrayPopShift::Mode mode) bool needsHoleCheck = thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED); bool maybeUndefined = returnTypes->hasType(types::Type::UndefinedType()); - bool barrier = PropertyReadNeedsTypeBarrier(cx, callInfo.thisArg(), NULL, returnTypes); + bool barrier; + if (!PropertyReadNeedsTypeBarrier(cx, callInfo.thisArg(), NULL, returnTypes, &barrier)) + return InliningStatus_Error; + if (barrier) returnType = MIRType_Value; @@ -350,7 +353,13 @@ IonBuilder::inlineArrayPush(CallInfo &callInfo) MDefinition *obj = callInfo.thisArg(); MDefinition *value = callInfo.getArg(0); - if (PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &value, /* canModify = */ false)) + bool writeNeedsBarrier; + if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &value, /* canModify = */ false, + &writeNeedsBarrier)) + { + return InliningStatus_Error; + } + if (writeNeedsBarrier) return InliningStatus_NotInlined; JS_ASSERT(obj == callInfo.thisArg() && value == callInfo.getArg(0)); @@ -1002,12 +1011,22 @@ IonBuilder::inlineUnsafePutElements(CallInfo &callInfo) MDefinition *id = callInfo.getArg(idxi); MDefinition *elem = callInfo.getArg(elemi); + bool isDenseNative = ElementAccessIsDenseNative(obj, id); + + bool writeNeedsBarrier = false; + if (isDenseNative) { + if (!PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, &elem, + /* canModify = */ false, + &writeNeedsBarrier)) + { + return InliningStatus_Error; + } + } + // We can only inline setelem on dense arrays that do not need type // barriers and on typed arrays. ScalarTypeRepresentation::Type arrayType; - if ((!ElementAccessIsDenseNative(obj, id) || - PropertyWriteNeedsTypeBarrier(cx, current, &obj, NULL, - &elem, /* canModify = */ false)) && + if ((!isDenseNative || writeNeedsBarrier) && !ElementAccessIsTypedArray(obj, id, &arrayType)) { return InliningStatus_NotInlined; diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index c27e30344a73..43ccefcdcf82 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2530,48 +2530,61 @@ jit::ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj) return types::TypeCanHaveExtraIndexedProperties(cx, types); } -MIRType -jit::DenseNativeElementType(JSContext *cx, MDefinition *obj) +bool +jit::DenseNativeElementType(JSContext *cx, MDefinition *obj, MIRType *result) { + JS_ASSERT(result); + *result = MIRType_None; + types::StackTypeSet *types = obj->resultTypeSet(); MIRType elementType = MIRType_None; unsigned count = types->getObjectCount(); for (unsigned i = 0; i < count; i++) { - if (types::TypeObject *object = types->getTypeOrSingleObject(cx, i)) { - if (object->unknownProperties()) - return MIRType_None; + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; - types::HeapTypeSet *elementTypes = object->getProperty(cx, JSID_VOID, false); - if (!elementTypes) - return MIRType_None; + if (!object) + continue; - MIRType type = MIRTypeFromValueType(elementTypes->getKnownTypeTag(cx)); - if (type == MIRType_None) - return MIRType_None; + if (object->unknownProperties()) + return true; - if (elementType == MIRType_None) - elementType = type; - else if (elementType != type) - return MIRType_None; - } + types::HeapTypeSet *elementTypes = object->getProperty(cx, JSID_VOID, false); + if (!elementTypes) + return true; + + MIRType type = MIRTypeFromValueType(elementTypes->getKnownTypeTag(cx)); + if (type == MIRType_None) + return true; + + if (elementType == MIRType_None) + elementType = type; + else if (elementType != type) + return true; } - return elementType; + *result = elementType; + return true; } bool jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name, - types::StackTypeSet *observed, bool updateObserved) + types::StackTypeSet *observed, bool updateObserved, bool *result) { // If the object being read from has types for the property which haven't // been observed at this access site, the read could produce a new type and // a barrier is needed. Note that this only covers reads from properties // which are accounted for by type information, i.e. native data properties // and elements. + JS_ASSERT(result); + *result = false; - if (object->unknownProperties()) + if (object->unknownProperties()) { + *result = true; return true; + } jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID; @@ -2596,8 +2609,10 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop } types::HeapTypeSet *property = object->getProperty(cx, id, false); - if (!property) + if (!property) { + *result = true; return true; + } // We need to consider possible types for the property both as an 'own' // property on the object and as inherited from any prototype. Type sets @@ -2606,8 +2621,10 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop if (!property->hasPropagatedProperty()) object->getFromPrototypes(cx, id, property); - if (!TypeSetIncludes(observed, MIRType_Value, property)) + if (!TypeSetIncludes(observed, MIRType_Value, property)) { + *result = true; return true; + } // Type information for singleton objects is not required to reflect the // initial 'undefined' value for native properties, in particular global @@ -2619,62 +2636,85 @@ jit::PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, Prop shape->hasDefaultGetter() && object->singleton->nativeGetSlot(shape->slot()).isUndefined()) { + *result = true; return true; } } property->addFreeze(cx); - return false; + *result = false; + return true; } bool jit::PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name, - types::StackTypeSet *observed) + types::StackTypeSet *observed, bool *result) { + JS_ASSERT(result); + *result = false; + if (observed->unknown()) - return false; + return true; types::TypeSet *types = obj->resultTypeSet(); - if (!types || types->unknownObject()) + if (!types || types->unknownObject()) { + *result = true; return true; + } bool updateObserved = types->getObjectCount() == 1; for (size_t i = 0; i < types->getObjectCount(); i++) { - types::TypeObject *object = types->getTypeOrSingleObject(cx, i); - if (object && PropertyReadNeedsTypeBarrier(cx, object, name, observed, updateObserved)) - return true; + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; + + if (object) { + if (!PropertyReadNeedsTypeBarrier(cx, object, name, observed, updateObserved, result)) + return false; + + if (*result) + return true; + } } - return false; + *result = false; + return true; } bool -jit::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name) +jit::PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name, bool *result) { + JS_ASSERT(result); + *result = false; // Determine if reading a property from obj is likely to be idempotent. jsid id = types::IdToTypeId(NameToId(name)); types::TypeSet *types = obj->resultTypeSet(); if (!types || types->unknownObject()) - return false; + return true; for (size_t i = 0; i < types->getObjectCount(); i++) { - if (types::TypeObject *object = types->getTypeOrSingleObject(cx, i)) { + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; + + if (object) { if (object->unknownProperties()) - return false; + return true; // Check if the property has been reconfigured or is a getter. types::HeapTypeSet *property = object->getProperty(cx, id, false); if (!property || property->isOwnProperty(cx, object, true)) - return false; + return true; } } + *result = true; return true; } -void +bool jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name, types::StackTypeSet *observed) { @@ -2686,25 +2726,28 @@ jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *na types::StackTypeSet *types = obj->resultTypeSet(); if (!types || types->unknownObject()) { observed->addType(cx, types::Type::AnyObjectType()); - return; + return true; } jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID; for (size_t i = 0; i < types->getObjectCount(); i++) { - types::TypeObject *object = types->getTypeOrSingleObject(cx, i); + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; + if (!object) continue; if (object->unknownProperties()) { observed->addType(cx, types::Type::AnyObjectType()); - return; + return true; } types::HeapTypeSet *property = object->getProperty(cx, id, false); if (property->unknownObject()) { observed->addType(cx, types::Type::AnyObjectType()); - return; + return true; } for (size_t i = 0; i < property->getObjectCount(); i++) { @@ -2714,6 +2757,8 @@ jit::AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *na observed->addType(cx, types::Type::ObjectType(object)); } } + + return true; } static bool @@ -2730,7 +2775,10 @@ TryAddTypeBarrierForWrite(JSContext *cx, MBasicBlock *current, types::StackTypeS types::HeapTypeSet *aggregateProperty = NULL; for (size_t i = 0; i < objTypes->getObjectCount(); i++) { - types::TypeObject *object = objTypes->getTypeOrSingleObject(cx, i); + types::TypeObject *object; + if (!objTypes->getTypeOrSingleObject(cx, i, &object)) + return false; + if (!object) continue; @@ -2808,8 +2856,12 @@ AddTypeGuard(MBasicBlock *current, MDefinition *obj, types::TypeObject *typeObje bool jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj, - PropertyName *name, MDefinition **pvalue, bool canModify) + PropertyName *name, MDefinition **pvalue, bool canModify, + bool *result) { + JS_ASSERT(result); + *result = false; + // If any value being written is not reflected in the type information for // objects which obj could represent, a type barrier is needed when writing // the value. As for propertyReadNeedsTypeBarrier, this only applies for @@ -2817,8 +2869,10 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit // properties and elements. types::StackTypeSet *types = (*pobj)->resultTypeSet(); - if (!types || types->unknownObject()) + if (!types || types->unknownObject()) { + *result = true; return true; + } jsid id = name ? types::IdToTypeId(NameToId(name)) : JSID_VOID; @@ -2829,7 +2883,10 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit bool success = true; for (size_t i = 0; i < types->getObjectCount(); i++) { - types::TypeObject *object = types->getTypeOrSingleObject(cx, i); + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; + if (!object || object->unknownProperties()) continue; @@ -2843,43 +2900,54 @@ jit::PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinit // types which the value could have but are not in the property, // or a VM call is required. A VM call is always required if pobj // and pvalue cannot be modified. - if (!canModify) + if (!canModify) { + *result = true; return true; + } success = TryAddTypeBarrierForWrite(cx, current, types, id, pvalue); break; } } if (success) - return false; + return true; // If all of the objects except one have property types which reflect the // value, and the remaining object has no types at all for the property, // add a guard that the object does not have that remaining object's type. - if (types->getObjectCount() <= 1) + if (types->getObjectCount() <= 1) { + *result = true; return true; + } types::TypeObject *excluded = NULL; for (size_t i = 0; i < types->getObjectCount(); i++) { - types::TypeObject *object = types->getTypeOrSingleObject(cx, i); + types::TypeObject *object; + if (!types->getTypeOrSingleObject(cx, i, &object)) + return false; + if (!object || object->unknownProperties()) continue; types::HeapTypeSet *property = object->getProperty(cx, id, false); - if (!property) + if (!property) { + *result = true; return true; + } if (TypeSetIncludes(property, (*pvalue)->type(), (*pvalue)->resultTypeSet())) continue; - if (!property->empty() || excluded) + if (!property->empty() || excluded) { + *result = true; return true; + } excluded = object; } JS_ASSERT(excluded); *pobj = AddTypeGuard(current, *pobj, excluded, /* bailOnEquality = */ true); - return false; + return true; } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index c722ab1362e7..2f4db13c0fe1 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -8510,17 +8510,17 @@ bool ElementAccessIsTypedArray(MDefinition *obj, MDefinition *id, ScalarTypeRepresentation::Type *arrayType); bool ElementAccessIsPacked(JSContext *cx, MDefinition *obj); bool ElementAccessHasExtraIndexedProperty(JSContext *cx, MDefinition *obj); -MIRType DenseNativeElementType(JSContext *cx, MDefinition *obj); +bool DenseNativeElementType(JSContext *cx, MDefinition *obj, MIRType *result); bool PropertyReadNeedsTypeBarrier(JSContext *cx, types::TypeObject *object, PropertyName *name, - types::StackTypeSet *observed, bool updateObserved = true); + types::StackTypeSet *observed, bool updateObserved, bool *result); bool PropertyReadNeedsTypeBarrier(JSContext *cx, MDefinition *obj, PropertyName *name, - types::StackTypeSet *observed); -bool PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name); -void AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name, + types::StackTypeSet *observed, bool *result); +bool PropertyReadIsIdempotent(JSContext *cx, MDefinition *obj, PropertyName *name, bool *result); +bool AddObjectsForPropertyRead(JSContext *cx, MDefinition *obj, PropertyName *name, types::StackTypeSet *observed); bool PropertyWriteNeedsTypeBarrier(JSContext *cx, MBasicBlock *current, MDefinition **pobj, PropertyName *name, MDefinition **pvalue, - bool canModify = true); + bool canModify, bool *result); } // namespace jit } // namespace js diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 9a493606cd1e..4d095639918a 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -511,7 +511,7 @@ class TypeSet inline TypeObjectKey *getObject(unsigned i) const; inline JSObject *getSingleObject(unsigned i) const; inline TypeObject *getTypeObject(unsigned i) const; - inline TypeObject *getTypeOrSingleObject(JSContext *cx, unsigned i) const; + inline bool getTypeOrSingleObject(JSContext *cx, unsigned i, TypeObject **obj) const; void setOwnProperty(bool configurable) { flags |= TYPE_FLAG_OWN_PROPERTY; diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 13d7e62d09e8..ca8ce798f237 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -1407,20 +1407,28 @@ TypeSet::getTypeObject(unsigned i) const return (key && !(uintptr_t(key) & 1)) ? (TypeObject *) key : NULL; } -inline TypeObject * -TypeSet::getTypeOrSingleObject(JSContext *cx, unsigned i) const +inline bool +TypeSet::getTypeOrSingleObject(JSContext *cx, unsigned i, TypeObject **result) const { + JS_ASSERT(result); JS_ASSERT(cx->compartment()->activeAnalysis); + + *result = NULL; + TypeObject *type = getTypeObject(i); if (!type) { JSObject *singleton = getSingleObject(i); if (!singleton) - return NULL; + return true; + type = singleton->uninlinedGetType(cx); - if (!type) + if (!type) { cx->compartment()->types.setPendingNukeTypes(cx); + return false; + } } - return type; + *result = type; + return true; } ///////////////////////////////////////////////////////////////////// From 7f2cb5dc2cf8d4669c37cfe4deedbe2f0a7c2f81 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Fri, 6 Sep 2013 11:35:11 -0700 Subject: [PATCH 10/36] Bug 905364 - Don't call into AllowXULXBLForPrincipal during SafeJSContext initialization. r=bz In the old world, we'd be saved by initializing the SafeJSContext early enough that we'd short-circuit in the nsContentUtils::IsInitialized() check. That's not the case anymore, so let's hande this explicitly. --- js/xpconnect/src/XPCJSContextStack.cpp | 4 ++-- js/xpconnect/src/XPCWrappedNativeScope.cpp | 22 +++++++++++++++------- js/xpconnect/src/xpcprivate.h | 2 ++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/js/xpconnect/src/XPCJSContextStack.cpp b/js/xpconnect/src/XPCJSContextStack.cpp index 798938b1709f..913fcdd68714 100644 --- a/js/xpconnect/src/XPCJSContextStack.cpp +++ b/js/xpconnect/src/XPCJSContextStack.cpp @@ -125,7 +125,7 @@ SafeFinalize(JSFreeOp *fop, JSObject* obj) DestroyProtoAndIfaceCache(obj); } -static JSClass global_class = { +JSClass xpc::SafeJSContextGlobalClass = { "global_for_XPCJSContextStack_SafeJSContext", XPCONNECT_GLOBAL_FLAGS, JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, @@ -161,7 +161,7 @@ XPCJSContextStack::GetSafeJSContext() JS::CompartmentOptions options; options.setZone(JS::SystemZone); - glob = xpc::CreateGlobalObject(mSafeJSContext, &global_class, principal, options); + glob = xpc::CreateGlobalObject(mSafeJSContext, &SafeJSContextGlobalClass, principal, options); if (!glob) MOZ_CRASH(); diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp index c2b71876c8fb..8255061cedcd 100644 --- a/js/xpconnect/src/XPCWrappedNativeScope.cpp +++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp @@ -18,6 +18,7 @@ using namespace mozilla; using namespace xpc; +using namespace JS; /***************************************************************************/ @@ -97,17 +98,24 @@ XPCWrappedNativeScope::GetNewOrUsed(JSContext *cx, JS::HandleObject aGlobal) } static bool -RemoteXULForbidsXBLScope(nsIPrincipal *aPrincipal) +RemoteXULForbidsXBLScope(nsIPrincipal *aPrincipal, HandleObject aGlobal) { - // We end up getting called during SSM bootstrapping to create the - // SafeJSContext. In that case, nsContentUtils isn't ready for us. - // - // Also check for random JSD scopes that don't have a principal. - if (!nsContentUtils::IsInitialized() || !aPrincipal) + // Check for random JSD scopes that don't have a principal. + if (!aPrincipal) + return false; + + // The SafeJSContext is lazily created, and tends to be created at really + // weird times, at least for xpcshell (often very early in startup or late + // in shutdown). Its scope isn't system principal, so if we proceeded we'd + // end up calling into AllowXULXBLForPrincipal, which depends on all kinds + // of persistent storage and permission machinery that may or not be running. + // We know the answer to the question here, so just short-circuit. + if (JS_GetClass(aGlobal) == &SafeJSContextGlobalClass) return false; // AllowXULXBLForPrincipal will return true for system principal, but we // don't want that here. + MOZ_ASSERT(nsContentUtils::IsInitialized()); if (nsContentUtils::IsSystemPrincipal(aPrincipal)) return false; @@ -161,7 +169,7 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx, // In addition to being pref-controlled, we also disable XBL scopes for // remote XUL domains, _except_ if we have an additional pref override set. nsIPrincipal *principal = GetPrincipal(); - mAllowXBLScope = !RemoteXULForbidsXBLScope(principal); + mAllowXBLScope = !RemoteXULForbidsXBLScope(principal, aGlobal); // Determine whether to use an XBL scope. mUseXBLScope = mAllowXBLScope; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 0558a0806b95..623aec194771 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3857,6 +3857,8 @@ GetObjectScope(JSObject *obj) extern bool gDebugMode; extern bool gDesiredDebugMode; +extern JSClass SafeJSContextGlobalClass; + JSObject* NewOutObject(JSContext* cx, JSObject* scope); bool IsOutObject(JSContext* cx, JSObject* obj); From 8bd42b92b1c23888d4d7efd9548cd53924fde8d2 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Fri, 6 Sep 2013 11:35:12 -0700 Subject: [PATCH 11/36] Bug 905364 - Force the SafeJSContext to fire up in xpcshell. r=bz --- js/xpconnect/shell/xpcshell.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp index 7417703b8710..7f436f51eeed 100644 --- a/js/xpconnect/shell/xpcshell.cpp +++ b/js/xpconnect/shell/xpcshell.cpp @@ -1676,6 +1676,11 @@ main(int argc, char **argv, char **envp) return 1; } + // Force the SafeJSContext to be created. This is a workaround for our + // implicit dependency on keeping at least one JSContext alive until the + // end of shutdown. This can go away when we get bug 905926 landed. + xpc->GetSafeJSContext(); + nsCOMPtr systemprincipal; // Fetch the system principal and store it away in a global, to use for // script compilation in Load() and ProcessFile() (including interactive From 30d81ff0177e54d81afe0f157a863d576d239ab1 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Fri, 6 Sep 2013 11:35:12 -0700 Subject: [PATCH 12/36] Bug 905364 - Stop using the SafeJSContext in nsScriptSecurityManager::Init. r=mrbkap With this patch, I've confirmed that we instantiate the SafeJSContext much later in startup, during nsAppStartupNotifier::Observe (which ends up invoking an XPCWrappedJS). As such, this should solve a number of our startup ordering woes. --- caps/include/nsScriptSecurityManager.h | 3 --- caps/src/nsScriptSecurityManager.cpp | 26 ++++++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/caps/include/nsScriptSecurityManager.h b/caps/include/nsScriptSecurityManager.h index 46e7563266d4..f5f10d42c3f5 100644 --- a/caps/include/nsScriptSecurityManager.h +++ b/caps/include/nsScriptSecurityManager.h @@ -488,9 +488,6 @@ private: InitDomainPolicy(JSContext* cx, const char* aPolicyName, DomainPolicy* aDomainPolicy); - // JS strings we need to clean up on shutdown - static jsid sEnabledID; - inline void ScriptSecurityPrefChanged(); diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index e0ad1047e76e..b968e39f9edd 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -77,6 +77,18 @@ nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr; JSRuntime *nsScriptSecurityManager::sRuntime = 0; bool nsScriptSecurityManager::sStrictFileOriginPolicy = true; +// Lazily initialized. Use the getter below. +static jsid sEnabledID = JSID_VOID; +static jsid +EnabledID() +{ + if (sEnabledID != JSID_VOID) + return sEnabledID; + AutoSafeJSContext cx; + sEnabledID = INTERNED_STRING_TO_JSID(cx, JS_InternString(cx, "enabled")); + return sEnabledID; +} + bool nsScriptSecurityManager::SubjectIsPrivileged() { @@ -1446,7 +1458,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, ClassInfoData nameData(nullptr, loadURIPrefGroup); SecurityLevel secLevel; - rv = LookupPolicy(aPrincipal, nameData, sEnabledID, + rv = LookupPolicy(aPrincipal, nameData, EnabledID(), nsIXPCSecurityManager::ACCESS_GET_PROPERTY, nullptr, &secLevel); if (NS_SUCCEEDED(rv) && secLevel.level == SCRIPT_SECURITY_ALL_ACCESS) @@ -1733,7 +1745,7 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx, ClassInfoData nameData(nullptr, jsPrefGroupName); SecurityLevel secLevel; - rv = LookupPolicy(aPrincipal, nameData, sEnabledID, + rv = LookupPolicy(aPrincipal, nameData, EnabledID(), nsIXPCSecurityManager::ACCESS_GET_PROPERTY, nullptr, &secLevel); if (NS_FAILED(rv) || secLevel.level == SCRIPT_SECURITY_NO_ACCESS) @@ -2330,14 +2342,6 @@ nsScriptSecurityManager::nsScriptSecurityManager(void) nsresult nsScriptSecurityManager::Init() { - JSContext* cx = GetSafeJSContext(); - if (!cx) return NS_ERROR_FAILURE; // this can happen of xpt loading fails - - ::JS_BeginRequest(cx); - if (sEnabledID == JSID_VOID) - sEnabledID = INTERNED_STRING_TO_JSID(cx, ::JS_InternString(cx, "enabled")); - ::JS_EndRequest(cx); - InitPrefs(); nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService); @@ -2378,8 +2382,6 @@ nsresult nsScriptSecurityManager::Init() static StaticRefPtr gScriptSecMan; -jsid nsScriptSecurityManager::sEnabledID = JSID_VOID; - nsScriptSecurityManager::~nsScriptSecurityManager(void) { Preferences::RemoveObservers(this, kObservedPrefs); From 0c8a2eeb6813fc3f3b1c0a254fc950b7df755e3f Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 6 Sep 2013 11:48:18 -0700 Subject: [PATCH 13/36] Bug 912606 - Warn on webgl context requests with mismatched ids. - r=bjacob --- .../html/content/src/HTMLCanvasElement.cpp | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/content/html/content/src/HTMLCanvasElement.cpp b/content/html/content/src/HTMLCanvasElement.cpp index cedec65b91fa..4f61108f465e 100644 --- a/content/html/content/src/HTMLCanvasElement.cpp +++ b/content/html/content/src/HTMLCanvasElement.cpp @@ -671,6 +671,14 @@ HTMLCanvasElement::GetContext(const nsAString& aContextId, return rv.ErrorCode(); } +static bool +IsContextIdWebGL(const nsAString& str) +{ + return str.EqualsLiteral("webgl") || + str.EqualsLiteral("experimental-webgl") || + str.EqualsLiteral("moz-webgl"); +} + already_AddRefed HTMLCanvasElement::GetContext(JSContext* aCx, const nsAString& aContextId, @@ -702,6 +710,20 @@ HTMLCanvasElement::GetContext(JSContext* aCx, } if (!mCurrentContextId.Equals(aContextId)) { + if (IsContextIdWebGL(aContextId) && + IsContextIdWebGL(mCurrentContextId)) + { + // Warn when we get a request for a webgl context with an id that differs + // from the id it was created with. + nsCString creationId = NS_LossyConvertUTF16toASCII(mCurrentContextId); + nsCString requestId = NS_LossyConvertUTF16toASCII(aContextId); + JS_ReportWarning(aCx, "WebGL: Retrieving a WebGL context from a canvas " + "via a request id ('%s') different from the id used " + "to create the context ('%s') is not allowed.", + requestId.get(), + creationId.get()); + } + //XXX eventually allow for more than one active context on a given canvas return nullptr; } From 6710a7e3693a798e20cea2f9b1bb0e8fc3283bc7 Mon Sep 17 00:00:00 2001 From: Jeff Gilbert Date: Fri, 6 Sep 2013 11:48:47 -0700 Subject: [PATCH 14/36] Bug 912606 - Test that mismatched webgl context request ids fails. - r=bjacob --- .../test/webgl/non-conf-tests/Makefile.in | 1 + .../test_webgl_request_mismatch.html | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 content/canvas/test/webgl/non-conf-tests/test_webgl_request_mismatch.html diff --git a/content/canvas/test/webgl/non-conf-tests/Makefile.in b/content/canvas/test/webgl/non-conf-tests/Makefile.in index 3a4a044e3ba0..aca1b163808f 100644 --- a/content/canvas/test/webgl/non-conf-tests/Makefile.in +++ b/content/canvas/test/webgl/non-conf-tests/Makefile.in @@ -5,4 +5,5 @@ MOCHITEST_FILES = \ test_webgl_conformance.html \ + test_webgl_request_mismatch.html \ $(NULL) diff --git a/content/canvas/test/webgl/non-conf-tests/test_webgl_request_mismatch.html b/content/canvas/test/webgl/non-conf-tests/test_webgl_request_mismatch.html new file mode 100644 index 000000000000..18da7fc89f25 --- /dev/null +++ b/content/canvas/test/webgl/non-conf-tests/test_webgl_request_mismatch.html @@ -0,0 +1,36 @@ + +WebGL test: Mismatched 'webgl' and 'experimental-webgl' context requests + + + + + + + + + + From 82b9523028091750ffd96f95d4fb34869bfa5e52 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Fri, 6 Sep 2013 13:50:24 -0400 Subject: [PATCH 15/36] Bug 913531 - Remove the unnecessary #includes from nsIXPConnect.idl; r=bholley --- .../base/public/nsHostObjectProtocolHandler.h | 2 +- content/base/src/nsXMLHttpRequest.cpp | 1 + content/base/src/nsXMLHttpRequest.h | 1 + content/html/content/src/HTMLAudioElement.cpp | 1 + content/media/WebVTTLoadListener.cpp | 1 + content/media/mediasource/MediaSource.cpp | 1 + content/media/mediasource/MediaSource.h | 2 ++ dom/base/nsDOMClassInfo.cpp | 1 + dom/base/nsDOMException.cpp | 1 + dom/base/nsGlobalWindow.h | 1 + dom/base/nsJSEnvironment.cpp | 1 + dom/base/nsJSTimeoutHandler.cpp | 1 + dom/bindings/BindingUtils.h | 1 + dom/devicestorage/DeviceStorage.h | 2 ++ dom/indexedDB/IndexedDatabase.h | 2 +- dom/workers/XMLHttpRequest.cpp | 1 + .../components/find/src/nsWebBrowserFind.cpp | 1 + js/xpconnect/idl/nsIXPCScriptable.idl | 1 + js/xpconnect/idl/nsIXPConnect.idl | 18 ++++++------------ js/xpconnect/src/nsXPConnect.cpp | 2 ++ js/xpconnect/src/xpcprivate.h | 1 + layout/style/nsCSSStyleSheet.cpp | 1 + layout/xul/base/src/nsBoxObject.cpp | 1 + layout/xul/tree/nsTreeSelection.cpp | 1 + 24 files changed, 32 insertions(+), 14 deletions(-) diff --git a/content/base/public/nsHostObjectProtocolHandler.h b/content/base/public/nsHostObjectProtocolHandler.h index a32d91e59206..85f06512b23f 100644 --- a/content/base/public/nsHostObjectProtocolHandler.h +++ b/content/base/public/nsHostObjectProtocolHandler.h @@ -9,6 +9,7 @@ #include "nsIProtocolHandler.h" #include "nsIURI.h" #include "nsCOMPtr.h" +#include "nsIInputStream.h" #define BLOBURI_SCHEME "blob" #define MEDIASTREAMURI_SCHEME "mediastream" @@ -18,7 +19,6 @@ class nsIDOMBlob; class nsIDOMMediaStream; class nsIPrincipal; -class nsIInputStream; namespace mozilla { namespace dom { diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 3498f49c4348..14708760e284 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -67,6 +67,7 @@ #include "nsCharSeparatedTokenizer.h" #include "nsFormData.h" #include "nsStreamListenerWrapper.h" +#include "xpcjsid.h" #include "nsWrapperCacheInlines.h" diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h index 9f98967cb7a7..ef2eb8e50fa6 100644 --- a/content/base/src/nsXMLHttpRequest.h +++ b/content/base/src/nsXMLHttpRequest.h @@ -48,6 +48,7 @@ class nsFormData; class nsIJARChannel; class nsILoadGroup; class nsIUnicodeDecoder; +class nsIJSID; namespace mozilla { diff --git a/content/html/content/src/HTMLAudioElement.cpp b/content/html/content/src/HTMLAudioElement.cpp index f4efc8ef05ef..3157f3309258 100644 --- a/content/html/content/src/HTMLAudioElement.cpp +++ b/content/html/content/src/HTMLAudioElement.cpp @@ -18,6 +18,7 @@ #include "AudioChannelCommon.h" #include #include "mozilla/Preferences.h" +#include "nsComponentManagerUtils.h" static bool IsAudioAPIEnabled() diff --git a/content/media/WebVTTLoadListener.cpp b/content/media/WebVTTLoadListener.cpp index 60ae7bd83805..fa0096433a46 100644 --- a/content/media/WebVTTLoadListener.cpp +++ b/content/media/WebVTTLoadListener.cpp @@ -6,6 +6,7 @@ #include "WebVTTLoadListener.h" #include "mozilla/dom/TextTrackCue.h" #include "mozilla/dom/HTMLTrackElement.h" +#include "nsIInputStream.h" namespace mozilla { namespace dom { diff --git a/content/media/mediasource/MediaSource.cpp b/content/media/mediasource/MediaSource.cpp index 5902a5cb6408..c617519c8d43 100644 --- a/content/media/mediasource/MediaSource.cpp +++ b/content/media/mediasource/MediaSource.cpp @@ -11,6 +11,7 @@ #include "SourceBuffer.h" #include "SourceBufferList.h" #include "nsContentTypeParser.h" +#include "nsIInputStream.h" #ifdef PR_LOGGING PRLogModuleInfo* gMediaSourceLog; diff --git a/content/media/mediasource/MediaSource.h b/content/media/mediasource/MediaSource.h index a5dc5589cd88..27420e9f184c 100644 --- a/content/media/mediasource/MediaSource.h +++ b/content/media/mediasource/MediaSource.h @@ -18,6 +18,8 @@ #include "nsWrapperCache.h" #include "nscore.h" +class nsIInputStream; + namespace mozilla { namespace dom { diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 35fcf01b8138..8bf96d7508a0 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -190,6 +190,7 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/Likely.h" #include "WindowNamedPropertiesHandler.h" +#include "nsIInterfaceInfoManager.h" #ifdef MOZ_TIME_MANAGER #include "TimeManager.h" diff --git a/dom/base/nsDOMException.cpp b/dom/base/nsDOMException.cpp index e1640c30a401..3fe994727610 100644 --- a/dom/base/nsDOMException.cpp +++ b/dom/base/nsDOMException.cpp @@ -15,6 +15,7 @@ #include "nsIDocument.h" #include "nsString.h" #include "prprf.h" +#include "nsIException.h" using namespace mozilla; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 15c0874d6143..d884ab0a0ec4 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -49,6 +49,7 @@ #include "mozilla/dom/EventTarget.h" #include "Units.h" +#include "nsComponentManagerUtils.h" #ifdef MOZ_B2G #include "nsIDOMWindowB2G.h" diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 43df9c29921d..7a457d8dcde0 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -55,6 +55,7 @@ #include "StructuredCloneTags.h" #include "mozilla/dom/ImageData.h" #include "mozilla/dom/ImageDataBinding.h" +#include "nsAXPCNativeCallContext.h" #include "nsJSPrincipals.h" diff --git a/dom/base/nsJSTimeoutHandler.cpp b/dom/base/nsJSTimeoutHandler.cpp index 2deacc095681..ffabe99bec98 100644 --- a/dom/base/nsJSTimeoutHandler.cpp +++ b/dom/base/nsJSTimeoutHandler.cpp @@ -17,6 +17,7 @@ #include "mozilla/Likely.h" #include #include "mozilla/dom/FunctionBinding.h" +#include "nsAXPCNativeCallContext.h" static const char kSetIntervalStr[] = "setInterval"; static const char kSetTimeoutStr[] = "setTimeout"; diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 884875ca1bb5..15405eab1264 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -28,6 +28,7 @@ #include "nsTraceRefcnt.h" #include "qsObjectHelper.h" #include "xpcpublic.h" +#include "nsIVariant.h" #include "nsWrapperCacheInlines.h" diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index 694e53d55ef6..eece1d7d40a9 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -23,6 +23,8 @@ #define DEVICESTORAGE_SDCARD "sdcard" #define DEVICESTORAGE_CRASHES "crashes" +class nsIInputStream; + namespace mozilla { namespace dom { class DeviceStorageEnumerationParameters; diff --git a/dom/indexedDB/IndexedDatabase.h b/dom/indexedDB/IndexedDatabase.h index 582dfc34c390..530b2cbc653e 100644 --- a/dom/indexedDB/IndexedDatabase.h +++ b/dom/indexedDB/IndexedDatabase.h @@ -17,6 +17,7 @@ #include "nsError.h" #include "nsStringGlue.h" #include "nsTArray.h" +#include "nsIInputStream.h" #define BEGIN_INDEXEDDB_NAMESPACE \ namespace mozilla { namespace dom { namespace indexedDB { @@ -28,7 +29,6 @@ using namespace mozilla::dom::indexedDB; class nsIDOMBlob; -class nsIInputStream; BEGIN_INDEXEDDB_NAMESPACE diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index 2a253eb5a3db..6b65e5a03f05 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -30,6 +30,7 @@ #include "DOMBindingInlines.h" #include "mozilla/Attributes.h" +#include "nsComponentManagerUtils.h" using namespace mozilla; diff --git a/embedding/components/find/src/nsWebBrowserFind.cpp b/embedding/components/find/src/nsWebBrowserFind.cpp index e7813e64001b..7d765741ce14 100644 --- a/embedding/components/find/src/nsWebBrowserFind.cpp +++ b/embedding/components/find/src/nsWebBrowserFind.cpp @@ -38,6 +38,7 @@ #include "nsFocusManager.h" #include "mozilla/Services.h" #include "mozilla/dom/Element.h" +#include "nsISimpleEnumerator.h" #if DEBUG #include "nsIWebNavigation.h" diff --git a/js/xpconnect/idl/nsIXPCScriptable.idl b/js/xpconnect/idl/nsIXPCScriptable.idl index 6ae28849805d..515a3fc112d2 100644 --- a/js/xpconnect/idl/nsIXPCScriptable.idl +++ b/js/xpconnect/idl/nsIXPCScriptable.idl @@ -6,6 +6,7 @@ #include "nsISupports.idl" #include "nsIXPConnect.idl" +#include "nsIClassInfo.idl" %{C++ #ifdef XP_WIN diff --git a/js/xpconnect/idl/nsIXPConnect.idl b/js/xpconnect/idl/nsIXPConnect.idl index e4b9d2502361..f30e1fb4656d 100644 --- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -7,26 +7,15 @@ /* The core XPConnect public interfaces. */ #include "nsISupports.idl" -#include "nsIClassInfo.idl" -#include "xpccomponents.idl" -#include "xpcjsid.idl" -#include "xpcexception.idl" -#include "nsIInterfaceInfo.idl" -#include "nsIInterfaceInfoManager.idl" -#include "nsIExceptionService.idl" -#include "nsIVariant.idl" -#include "nsIObjectOutputStream.idl" -#include "nsIObjectInputStream.idl" %{ C++ #include "jspubtd.h" #include "js/TypeDecls.h" -#include "xptinfo.h" -#include "nsAXPCNativeCallContext.h" struct JSFreeOp; class nsWrapperCache; +class nsAXPCNativeCallContext; %} /***************************************************************************/ @@ -58,6 +47,11 @@ interface nsIXPConnectWrappedNative; interface nsIInterfaceInfo; interface nsIXPCSecurityManager; interface nsIPrincipal; +interface nsIClassInfo; +interface nsIVariant; +interface nsIStackFrame; +interface nsIObjectInputStream; +interface nsIObjectOutputStream; /***************************************************************************/ [uuid(909e8641-7c54-4dff-9b94-ba631f057b33)] diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 3c4dde7eb329..6cfb20410a22 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -53,6 +53,8 @@ #include "nsICycleCollectorListener.h" #include "nsThread.h" #include "mozilla/XPTInterfaceInfoManager.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 623aec194771..5ea6f85cac60 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -160,6 +160,7 @@ #include "SandboxPrivate.h" #include "BackstagePass.h" #include "nsCxPusher.h" +#include "nsAXPCNativeCallContext.h" #ifdef XP_WIN // Nasty MS defines diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index 1edc78d248c0..e4712a18bba1 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -40,6 +40,7 @@ #include "nsDOMClassInfoID.h" #include "mozilla/Likely.h" #include "mozilla/dom/CSSStyleSheetBinding.h" +#include "nsComponentManagerUtils.h" using namespace mozilla; using namespace mozilla::dom; diff --git a/layout/xul/base/src/nsBoxObject.cpp b/layout/xul/base/src/nsBoxObject.cpp index 67dd1b40cec9..90c9ad7477be 100644 --- a/layout/xul/base/src/nsBoxObject.cpp +++ b/layout/xul/base/src/nsBoxObject.cpp @@ -23,6 +23,7 @@ #include "nsISupportsPrimitives.h" #include "nsSupportsPrimitives.h" #include "mozilla/dom/Element.h" +#include "nsComponentManagerUtils.h" using namespace mozilla::dom; diff --git a/layout/xul/tree/nsTreeSelection.cpp b/layout/xul/tree/nsTreeSelection.cpp index e6c6cc89cb8b..e51045202c37 100644 --- a/layout/xul/tree/nsTreeSelection.cpp +++ b/layout/xul/tree/nsTreeSelection.cpp @@ -18,6 +18,7 @@ #include "nsAsyncDOMEvent.h" #include "nsEventDispatcher.h" #include "nsAutoPtr.h" +#include "nsComponentManagerUtils.h" // A helper class for managing our ranges of selection. struct nsTreeRange From eecd5915b6cebcde705285f53462713fa44e940b Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Tue, 27 Aug 2013 12:34:44 -0700 Subject: [PATCH 16/36] Bug 907353 - Disable second component when rtcp-mux r=ekr --- .../signaling/src/media/VcmSIPCCBinding.cpp | 48 +++++++++++++++++++ .../signaling/src/sipcc/core/gsm/gsm_sdp.c | 11 +++++ .../src/sipcc/core/includes/config.h | 2 +- .../webrtc/signaling/src/sipcc/include/vcm.h | 8 ++++ .../signaling/test/signaling_unittests.cpp | 2 +- 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp index 87c69f4083a2..0ab6ee077408 100644 --- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp +++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp @@ -2859,4 +2859,52 @@ int vcmOnSdpParseError(const char *peerconnection, const char *message) { return 0; } +/** + * vcmDisableRtcpComponent_m + * + * If we are doing rtcp-mux we need to disable component number 2 in the ICE + * layer. Otherwise we will wait for it to connect when it is unused + */ +static int vcmDisableRtcpComponent_m(const char *peerconnection, int level) { +#ifdef MOZILLA_INTERNAL_API + MOZ_ASSERT(NS_IsMainThread()); +#endif + MOZ_ASSERT(level > 0); + + sipcc::PeerConnectionWrapper pc(peerconnection); + ENSURE_PC(pc, VCM_ERROR); + + CSFLogDebug( logTag, "%s: disabling rtcp component %d", __FUNCTION__, level); + mozilla::RefPtr stream = pc.impl()->media()-> + ice_media_stream(level-1); + MOZ_ASSERT(stream); + if (!stream) { + return VCM_ERROR; + } + + // The second component is for RTCP + nsresult res = stream->DisableComponent(2); + MOZ_ASSERT(NS_SUCCEEDED(res)); + if (!NS_SUCCEEDED(res)) { + return VCM_ERROR; + } + + return 0; +} + +/** + * vcmDisableRtcpComponent + * + * If we are doing rtcp-mux we need to disable component number 2 in the ICE + * layer. Otherwise we will wait for it to connect when it is unused + */ +int vcmDisableRtcpComponent(const char *peerconnection, int level) { + int ret; + mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(), + WrapRunnableNMRet(&vcmDisableRtcpComponent_m, + peerconnection, + level, + &ret)); + return ret; +} diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c index d814d354741f..892e9d8b9388 100644 --- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c @@ -6834,6 +6834,17 @@ gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p) if (!GSMSDP_MEDIA_ENABLED(media)) continue; + /* If we are muxing, disable the second + component of the ICE stream */ + if (media->rtcp_mux) { + vcm_res = vcmDisableRtcpComponent(dcb_p->peerconnection, + media->level); + + if (vcm_res) { + return (CC_CAUSE_SETTING_ICE_SESSION_PARAMETERS_FAILED); + } + } + sdp_res = sdp_attr_get_ice_attribute(sdp_p->dest_sdp, media->level, 0, SDP_ATTR_ICE_UFRAG, 1, &ufrag); if (sdp_res != SDP_SUCCESS) diff --git a/media/webrtc/signaling/src/sipcc/core/includes/config.h b/media/webrtc/signaling/src/sipcc/core/includes/config.h index 6cdcfa3bde31..0b6e8a54d99a 100755 --- a/media/webrtc/signaling/src/sipcc/core/includes/config.h +++ b/media/webrtc/signaling/src/sipcc/core/includes/config.h @@ -179,7 +179,7 @@ static const int gDscpCallControl = 1; static const int gSpeakerEnabled = 1; static const char gExternalNumberMask[] = ""; static const char gVersion[] = "0.1"; -static const boolean gRTCPMUX = FALSE; +static const boolean gRTCPMUX = TRUE; static boolean gRTPSAVPF = TRUE; /* TRUE = RTP/SAVPF , FALSE = RTP/SAVP */ static const boolean gMAXAVBITRATE = FALSE; /* Following six are OPUS fmtp options */ static const boolean gMAXCODEDAUDIOBW = FALSE; diff --git a/media/webrtc/signaling/src/sipcc/include/vcm.h b/media/webrtc/signaling/src/sipcc/include/vcm.h index 71688e816416..aa1266c92e98 100755 --- a/media/webrtc/signaling/src/sipcc/include/vcm.h +++ b/media/webrtc/signaling/src/sipcc/include/vcm.h @@ -1035,6 +1035,14 @@ int vcmGetILBCMode(); */ int vcmOnSdpParseError(const char *peercconnection, const char *message); +/** + * vcmDisableRtcpComponent + * + * If we are doing rtcp-mux we need to disable component number 2 in the ICE + * layer. Otherwise we will wait for it to connect when it is unused + */ +int vcmDisableRtcpComponent(const char *peerconnection, int level); + //Using C++ for gips. This is the end of extern "C" above. #ifdef __cplusplus } diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index 8a1b4f470f79..3755a1c6e05d 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -37,7 +37,7 @@ MtransportTestUtils *test_utils; nsCOMPtr gThread; static int kDefaultTimeout = 5000; -static bool fRtcpMux = false; +static bool fRtcpMux = true; static std::string callerName = "caller"; static std::string calleeName = "callee"; From f9cdc752b15e7f43046a5ad5dcc925554ff6d48e Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Fri, 6 Sep 2013 13:32:55 -0700 Subject: [PATCH 17/36] Bug 912299 - Make RefCounted's refcount field mutable. r=waldo --- mfbt/RefPtr.h | 8 ++++---- mozglue/linker/ElfLoader.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mfbt/RefPtr.h b/mfbt/RefPtr.h index 3c275afdc7c1..72c79045546c 100644 --- a/mfbt/RefPtr.h +++ b/mfbt/RefPtr.h @@ -68,18 +68,18 @@ class RefCounted public: // Compatibility with nsRefPtr. - void AddRef() { + void AddRef() const { MOZ_ASSERT(refCnt >= 0); ++refCnt; } - void Release() { + void Release() const { MOZ_ASSERT(refCnt > 0); if (0 == --refCnt) { #ifdef DEBUG refCnt = detail::DEAD; #endif - delete static_cast(this); + delete static_cast(this); } } @@ -93,7 +93,7 @@ class RefCounted } private: - typename Conditional, int>::Type refCnt; + mutable typename Conditional, int>::Type refCnt; }; } diff --git a/mozglue/linker/ElfLoader.h b/mozglue/linker/ElfLoader.h index e0c07ca37a5f..000a8359a116 100644 --- a/mozglue/linker/ElfLoader.h +++ b/mozglue/linker/ElfLoader.h @@ -70,7 +70,7 @@ class LibHandle; namespace mozilla { namespace detail { -template <> inline void RefCounted::Release(); +template <> inline void RefCounted::Release() const; template <> inline RefCounted::~RefCounted() { @@ -215,7 +215,7 @@ private: namespace mozilla { namespace detail { -template <> inline void RefCounted::Release() { +template <> inline void RefCounted::Release() const { #ifdef DEBUG if (refCnt > 0x7fff0000) MOZ_ASSERT(refCnt > 0x7fffdead); @@ -228,7 +228,7 @@ template <> inline void RefCounted::Release() { #else refCnt = 1; #endif - delete static_cast(this); + delete static_cast(this); } } } From 86cac34e69fd3301ee354c0957dcc10480b8ead3 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 6 Sep 2013 13:40:34 -0700 Subject: [PATCH 18/36] Bug 911233, part 1 - Minor cycle collector cleanups. r=smaug --- js/xpconnect/src/xpcprivate.h | 1 - xpcom/base/nsCycleCollector.cpp | 38 ++++++++++++++++----------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 5ea6f85cac60..f225fb711a2d 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -97,7 +97,6 @@ #include "nsXPCOM.h" #include "nsAutoPtr.h" #include "nsCycleCollectionParticipant.h" -#include "mozilla/CycleCollectedJSRuntime.h" #include "nsDebug.h" #include "nsISupports.h" #include "nsIServiceManager.h" diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index c1cf5784fddd..0a0007e13c11 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -105,7 +105,6 @@ #include "mozilla/CycleCollectedJSRuntime.h" #include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionNoteRootCallback.h" -#include "nsBaseHashtable.h" #include "nsHashKeys.h" #include "nsDeque.h" #include "nsCycleCollector.h" @@ -841,7 +840,7 @@ public: }; static bool -AddPurpleRoot(GCGraphBuilder &builder, void *root, nsCycleCollectionParticipant *cp); +AddPurpleRoot(GCGraphBuilder &aBuilder, void *aRoot, nsCycleCollectionParticipant *aParti); struct SelectPointersVisitor { @@ -893,6 +892,7 @@ class nsCycleCollector friend class GCGraphBuilder; bool mCollectionInProgress; + // mScanInProgress should be false when we're collecting white objects. bool mScanInProgress; nsCycleCollectorResults *mResults; TimeStamp mCollectionStart; @@ -945,7 +945,7 @@ public: } void SelectPurple(GCGraphBuilder &builder); - void MarkRoots(GCGraphBuilder &builder); + void MarkRoots(GCGraphBuilder &aBuilder); void ScanRoots(); void ScanWeakMaps(); @@ -1896,12 +1896,12 @@ GCGraphBuilder::NoteWeakMapping(void *map, void *key, void *kdelegate, void *val } static bool -AddPurpleRoot(GCGraphBuilder &builder, void *root, nsCycleCollectionParticipant *cp) +AddPurpleRoot(GCGraphBuilder &aBuilder, void *aRoot, nsCycleCollectionParticipant *aParti) { - CanonicalizeParticipant(&root, &cp); + CanonicalizeParticipant(&aRoot, &aParti); - if (builder.WantAllTraces() || !cp->CanSkipInCC(root)) { - PtrInfo *pinfo = builder.AddNode(root, cp); + if (aBuilder.WantAllTraces() || !aParti->CanSkipInCC(aRoot)) { + PtrInfo *pinfo = aBuilder.AddNode(aRoot, aParti); if (!pinfo) { return false; } @@ -2020,7 +2020,7 @@ public: } } - bool HasSnowWhiteObjects() + bool HasSnowWhiteObjects() const { return mObjects.Length() > 0; } @@ -2130,23 +2130,25 @@ nsCycleCollector::ForgetSkippable(bool aRemoveChildlessNodes, } MOZ_NEVER_INLINE void -nsCycleCollector::MarkRoots(GCGraphBuilder &builder) +nsCycleCollector::MarkRoots(GCGraphBuilder &aBuilder) { - mGraph.mRootCount = builder.Count(); + mGraph.mRootCount = aBuilder.Count(); // read the PtrInfo out of the graph that we are building NodePool::Enumerator queue(mGraph.mNodes); while (!queue.IsDone()) { PtrInfo *pi = queue.GetNext(); CC_AbortIfNull(pi); - builder.Traverse(pi); - if (queue.AtBlockEnd()) - builder.SetLastChild(); + aBuilder.Traverse(pi); + if (queue.AtBlockEnd()) { + aBuilder.SetLastChild(); + } + } + if (mGraph.mRootCount > 0) { + aBuilder.SetLastChild(); } - if (mGraph.mRootCount > 0) - builder.SetLastChild(); - if (builder.RanOutOfMemory()) { + if (aBuilder.RanOutOfMemory()) { NS_ASSERTION(false, "Ran out of memory while building cycle collector graph"); Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_OOM, true); @@ -2596,10 +2598,6 @@ nsCycleCollector::FixGrayBits(bool aForceGC) } TimeLog timeLog; - - // mJSRuntime->Collect() must be called from the main thread, - // because it invokes XPCJSRuntime::GCCallback(cx, JSGC_BEGIN) - // which returns false if not in the main thread. mJSRuntime->Collect(aForceGC ? JS::gcreason::SHUTDOWN_CC : JS::gcreason::CC_FORCED); timeLog.Checkpoint("GC()"); } From 9ae420c35194bf5426c9bdada7d3577822c638ff Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 6 Sep 2013 13:41:11 -0700 Subject: [PATCH 19/36] Bug 911233, part 2 - Inline SelectPurple. r=smaug --- xpcom/base/nsCycleCollector.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 0a0007e13c11..15af1a27cb72 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -944,7 +944,6 @@ public: mForgetSkippableCB = aForgetSkippableCB; } - void SelectPurple(GCGraphBuilder &builder); void MarkRoots(GCGraphBuilder &aBuilder); void ScanRoots(); void ScanWeakMaps(); @@ -2112,12 +2111,6 @@ nsCycleCollector::FreeSnowWhite(bool aUntilNoSWInPurpleBuffer) return hadSnowWhiteObjects; } -void -nsCycleCollector::SelectPurple(GCGraphBuilder &builder) -{ - mPurpleBuf.SelectPointers(builder); -} - void nsCycleCollector::ForgetSkippable(bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing) @@ -2787,9 +2780,8 @@ nsCycleCollector::BeginCollection(ccType aCCType, } mScanInProgress = true; - SelectPurple(builder); - - timeLog.Checkpoint("SelectPurple()"); + mPurpleBuf.SelectPointers(builder); + timeLog.Checkpoint("SelectPointers()"); if (builder.Count() > 0) { // The main Bacon & Rajan collection algorithm. From 9b9141a21ee591f2dfb5f0355b35a0d14a2ecbbd Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 6 Sep 2013 13:41:42 -0700 Subject: [PATCH 20/36] Bug 911233, part 3 - Add more CheckThreadSafety calls to the cycle collector. r=khuey --- xpcom/base/nsCycleCollector.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 15af1a27cb72..aefd3e03a911 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -936,11 +936,13 @@ public: void SetBeforeUnlinkCallback(CC_BeforeUnlinkCallback aBeforeUnlinkCB) { + CheckThreadSafety(); mBeforeUnlinkCB = aBeforeUnlinkCB; } void SetForgetSkippableCallback(CC_ForgetSkippableCallback aForgetSkippableCB) { + CheckThreadSafety(); mForgetSkippableCB = aForgetSkippableCB; } @@ -2098,6 +2100,8 @@ nsPurpleBuffer::RemoveSkippable(nsCycleCollector* aCollector, bool nsCycleCollector::FreeSnowWhite(bool aUntilNoSWInPurpleBuffer) { + CheckThreadSafety(); + bool hadSnowWhiteObjects = false; do { SnowWhiteKiller visitor(mPurpleBuf.Count()); @@ -2115,6 +2119,7 @@ void nsCycleCollector::ForgetSkippable(bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing) { + CheckThreadSafety(); if (mJSRuntime) { mJSRuntime->PrepareForForgetSkippable(); } @@ -2832,12 +2837,15 @@ nsCycleCollector::FinishCollection(nsICycleCollectorListener *aListener) uint32_t nsCycleCollector::SuspectedCount() { + CheckThreadSafety(); return mPurpleBuf.Count(); } void nsCycleCollector::Shutdown() { + CheckThreadSafety(); + // Always delete snow white objects. FreeSnowWhite(true); @@ -3204,7 +3212,6 @@ nsCycleCollector_shutdown() if (data) { MOZ_ASSERT(data->mCollector); PROFILER_LABEL("CC", "nsCycleCollector_shutdown"); - data->mCollector->CheckThreadSafety(); data->mCollector->Shutdown(); delete data->mCollector; data->mCollector = nullptr; From 45586448285097613be8578e5b355724f2c0ae09 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Fri, 6 Sep 2013 13:42:27 -0700 Subject: [PATCH 21/36] Bug 913080 - Make GCGraphBuilder's hash table initialization infallible. r=smaug --- xpcom/base/nsCycleCollector.cpp | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index aefd3e03a911..c0b4bc0bd289 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -979,7 +979,7 @@ public: void CleanupAfterCollection(); // Start and finish an individual collection. - bool BeginCollection(ccType aCCType, nsICycleCollectorListener *aListener); + void BeginCollection(ccType aCCType, nsICycleCollectorListener *aListener); bool FinishCollection(nsICycleCollectorListener *aListener); bool FreeSnowWhite(bool aUntilNoSWInPurpleBuffer); @@ -1564,7 +1564,6 @@ public: nsICycleCollectorListener *aListener, bool aMergeZones); ~GCGraphBuilder(); - bool Initialized(); bool WantAllTraces() const { @@ -1658,8 +1657,7 @@ GCGraphBuilder::GCGraphBuilder(nsCycleCollector *aCollector, { if (!PL_DHashTableInit(&mPtrToNodeMap, &PtrNodeOps, nullptr, sizeof(PtrToNodeEntry), 32768)) { - mPtrToNodeMap.ops = nullptr; - mRanOutOfMemory = true; + MOZ_CRASH(); } if (aJSRuntime) { @@ -1692,12 +1690,6 @@ GCGraphBuilder::~GCGraphBuilder() PL_DHashTableFinish(&mPtrToNodeMap); } -bool -GCGraphBuilder::Initialized() -{ - return !!mPtrToNodeMap.ops; -} - PtrInfo* GCGraphBuilder::AddNode(void *s, nsCycleCollectionParticipant *aParticipant) { @@ -2681,9 +2673,10 @@ nsCycleCollector::ShutdownCollect(nsICycleCollectorListener *aListener) if (aListener && NS_FAILED(aListener->Begin())) aListener = nullptr; FreeSnowWhite(true); - if (!(BeginCollection(ShutdownCC, aListener) && - FinishCollection(aListener))) + BeginCollection(ShutdownCC, aListener); + if (!FinishCollection(aListener)) { break; + } } CleanupAfterCollection(); @@ -2716,10 +2709,7 @@ nsCycleCollector::Collect(ccType aCCType, aListener = nullptr; } - if (!BeginCollection(aCCType, aListener)) { - return; - } - + BeginCollection(aCCType, aListener); FinishCollection(aListener); CleanupAfterCollection(); } @@ -2759,7 +2749,7 @@ nsCycleCollector::ShouldMergeZones(ccType aCCType) } } -bool +void nsCycleCollector::BeginCollection(ccType aCCType, nsICycleCollectorListener *aListener) { @@ -2773,11 +2763,6 @@ nsCycleCollector::BeginCollection(ccType aCCType, GCGraphBuilder builder(this, mGraph, mJSRuntime, aListener, mergeZones); - if (!builder.Initialized()) { - NS_ASSERTION(false, "Failed to initialize GCGraphBuilder, will probably leak."); - Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_OOM, true); - return false; - } if (mJSRuntime) { mJSRuntime->BeginCycleCollection(builder); @@ -2816,8 +2801,6 @@ nsCycleCollector::BeginCollection(ccType aCCType, } else { mScanInProgress = false; } - - return true; } bool From fdd9e3f2a6b10c238039ed04756c8be0ffa81053 Mon Sep 17 00:00:00 2001 From: Stephan Schreiber Date: Fri, 6 Sep 2013 16:41:55 -0400 Subject: [PATCH 22/36] Bug 910845 - Add a wrapper for mmap() in order to keep the high 17-bits of JS pointers cleared on IA64. r=billm --- js/src/gc/Memory.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp index cb065942e682..96b5edc8dab1 100644 --- a/js/src/gc/Memory.cpp +++ b/js/src/gc/Memory.cpp @@ -309,6 +309,40 @@ gc::InitMemorySubsystem(JSRuntime *rt) rt->gcSystemPageSize = rt->gcSystemAllocGranularity = size_t(sysconf(_SC_PAGESIZE)); } +static inline void * +gc::MapMemory(size_t length, int prot, int flags, int fd, off_t offset) +{ +#if defined(__ia64__) + /* + * The JS engine assumes that all allocated pointers have their high 17 bits clear, + * which ia64's mmap doesn't support directly. However, we can emulate it by passing + * mmap an "addr" parameter with those bits clear. The mmap will return that address, + * or the nearest available memory above that address, providing a near-guarantee + * that those bits are clear. If they are not, we return NULL below to indicate + * out-of-memory. + * + * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual + * address space. + * + * See Bug 589735 for more information. + */ + void *region = mmap((void*)0x0000070000000000, length, prot, flags, fd, offset); + if (region == MAP_FAILED) + return MAP_FAILED; + /* + * If the allocated memory doesn't have its upper 17 bits clear, consider it + * as out of memory. + */ + if ((uintptr_t(region) + (length - 1)) & 0xffff800000000000) { + JS_ALWAYS_TRUE(0 == munmap(region, length)); + return MAP_FAILED; + } + return region; +#else + return mmap(NULL, length, prot, flags, fd, offset); +#endif +} + void * gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment) { @@ -322,12 +356,15 @@ gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment) /* Special case: If we want page alignment, no further work is needed. */ if (alignment == rt->gcSystemAllocGranularity) { - return mmap(NULL, size, prot, flags, -1, 0); + void *region = MapMemory(size, prot, flags, -1, 0); + if (region == MAP_FAILED) + return NULL; + return region; } /* Overallocate and unmap the region's edges. */ size_t reqSize = Min(size + 2 * alignment, 2 * size); - void *region = mmap(NULL, reqSize, prot, flags, -1, 0); + void *region = MapMemory(reqSize, prot, flags, -1, 0); if (region == MAP_FAILED) return NULL; From 107bcf1f66caf3a176de8e0093bc68584823c604 Mon Sep 17 00:00:00 2001 From: Michael Harrison Date: Fri, 6 Sep 2013 16:44:26 -0400 Subject: [PATCH 23/36] Bug 909768 - Replace idl::GeoPositionOptions with dom::PositionOptions. r=jdm --- .../geolocation/nsIDOMGeoGeolocation.idl | 19 +++---- dom/ipc/ContentParent.cpp | 6 +-- dom/src/geolocation/nsGeolocation.cpp | 49 +++++++++---------- dom/src/geolocation/nsGeolocation.h | 4 +- js/xpconnect/src/dictionary_helper_gen.conf | 1 - 5 files changed, 36 insertions(+), 43 deletions(-) diff --git a/dom/interfaces/geolocation/nsIDOMGeoGeolocation.idl b/dom/interfaces/geolocation/nsIDOMGeoGeolocation.idl index 9f4114b5edc0..ad4e57e7131b 100644 --- a/dom/interfaces/geolocation/nsIDOMGeoGeolocation.idl +++ b/dom/interfaces/geolocation/nsIDOMGeoGeolocation.idl @@ -8,26 +8,23 @@ interface nsIDOMGeoPositionCallback; interface nsIDOMGeoPositionErrorCallback; %{C++ -#include "DictionaryHelpers.h" +namespace mozilla { +namespace dom { +class PositionOptions; +} +} %} -dictionary GeoPositionOptions -{ - boolean enableHighAccuracy; - long timeout; - long maximumAge; -}; - -[ptr] native NamespacedGeoPositionOptions(mozilla::idl::GeoPositionOptions); +[ptr] native NamespacedPositionOptions(mozilla::dom::PositionOptions); [builtinclass, uuid(1bc7d103-c7ae-4467-881c-21a8dfa17938)] interface nsIDOMGeoGeolocation : nsISupports { int32_t watchPosition(in nsIDOMGeoPositionCallback callback, in nsIDOMGeoPositionErrorCallback errorCallback, - in NamespacedGeoPositionOptions options); + in NamespacedPositionOptions options); void getCurrentPosition(in nsIDOMGeoPositionCallback callback, in nsIDOMGeoPositionErrorCallback errorCallback, - in NamespacedGeoPositionOptions options); + in NamespacedPositionOptions options); void clearWatch(in long watchId); }; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 700f83c5eee8..8f7555931e5d 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -34,6 +34,7 @@ #include "mozilla/dom/bluetooth/PBluetoothParent.h" #include "mozilla/dom/PFMRadioParent.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h" +#include "mozilla/dom/GeolocationBinding.h" #include "mozilla/dom/telephony/TelephonyParent.h" #include "SmsParent.h" #include "mozilla/Hal.h" @@ -150,7 +151,6 @@ using namespace mozilla::dom::power; using namespace mozilla::dom::mobilemessage; using namespace mozilla::dom::telephony; using namespace mozilla::hal; -using namespace mozilla::idl; using namespace mozilla::ipc; using namespace mozilla::layers; using namespace mozilla::net; @@ -2642,8 +2642,8 @@ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy) return -1; } - GeoPositionOptions* options = new GeoPositionOptions(); - options->enableHighAccuracy = highAccuracy; + PositionOptions* options = new PositionOptions(); + options->mEnableHighAccuracy = highAccuracy; int32_t retval = 1; geo->WatchPosition(watcher, nullptr, options, &retval); return retval; diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp index 500bbdf75ef2..a650939c6f30 100644 --- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -71,13 +71,13 @@ class nsGeolocationRequest nsGeolocationRequest(Geolocation* aLocator, const GeoPositionCallback& aCallback, const GeoPositionErrorCallback& aErrorCallback, - idl::GeoPositionOptions* aOptions, + PositionOptions* aOptions, bool aWatchPositionRequest = false, int32_t aWatchId = 0); void Shutdown(); void SendLocation(nsIDOMGeoPosition* location); - bool WantsHighAccuracy() {return mOptions && mOptions->enableHighAccuracy;} + bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;} void SetTimeoutTimer(); nsIPrincipal* GetPrincipal(); @@ -94,7 +94,7 @@ class nsGeolocationRequest nsCOMPtr mTimeoutTimer; GeoPositionCallback mCallback; GeoPositionErrorCallback mErrorCallback; - nsAutoPtr mOptions; + nsAutoPtr mOptions; nsRefPtr mLocator; @@ -102,15 +102,14 @@ class nsGeolocationRequest bool mShutdown; }; -static idl::GeoPositionOptions* -GeoPositionOptionsFromPositionOptions(const PositionOptions& aOptions) +static PositionOptions* +CreatePositionOptionsCopy(const PositionOptions& aOptions) { - nsAutoPtr geoOptions( - new idl::GeoPositionOptions()); + nsAutoPtr geoOptions(new PositionOptions()); - geoOptions->enableHighAccuracy = aOptions.mEnableHighAccuracy; - geoOptions->maximumAge = aOptions.mMaximumAge; - geoOptions->timeout = aOptions.mTimeout; + geoOptions->mEnableHighAccuracy = aOptions.mEnableHighAccuracy; + geoOptions->mMaximumAge = aOptions.mMaximumAge; + geoOptions->mTimeout = aOptions.mTimeout; return geoOptions.forget(); } @@ -336,7 +335,7 @@ PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback) nsGeolocationRequest::nsGeolocationRequest(Geolocation* aLocator, const GeoPositionCallback& aCallback, const GeoPositionErrorCallback& aErrorCallback, - idl::GeoPositionOptions* aOptions, + PositionOptions* aOptions, bool aWatchPositionRequest, int32_t aWatchId) : mIsWatchPositionRequest(aWatchPositionRequest), @@ -460,11 +459,11 @@ nsGeolocationRequest::Allow() uint32_t maximumAge = 30 * PR_MSEC_PER_SEC; if (mOptions) { - if (mOptions->maximumAge >= 0) { - maximumAge = mOptions->maximumAge; + if (mOptions->mMaximumAge >= 0) { + maximumAge = mOptions->mMaximumAge; } } - gs->SetHigherAccuracy(mOptions && mOptions->enableHighAccuracy); + gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy); bool canUseCache = lastPosition && maximumAge > 0 && (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <= @@ -497,7 +496,7 @@ nsGeolocationRequest::SetTimeoutTimer() } int32_t timeout; - if (mOptions && (timeout = mOptions->timeout) != 0) { + if (mOptions && (timeout = mOptions->mTimeout) != 0) { if (timeout < 0) { timeout = 0; @@ -600,7 +599,7 @@ nsGeolocationRequest::Shutdown() // This should happen last, to ensure that this request isn't taken into consideration // when deciding whether existing requests still require high accuracy. - if (mOptions && mOptions->enableHighAccuracy) { + if (mOptions && mOptions->mEnableHighAccuracy) { nsRefPtr gs = nsGeolocationService::GetGeolocationService(); if (gs) { gs->SetHigherAccuracy(false); @@ -1200,9 +1199,8 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback, GeoPositionCallback successCallback(&aCallback); GeoPositionErrorCallback errorCallback(aErrorCallback); - nsresult rv = - GetCurrentPosition(successCallback, errorCallback, - GeoPositionOptionsFromPositionOptions(aOptions)); + nsresult rv = GetCurrentPosition(successCallback, errorCallback, + CreatePositionOptionsCopy(aOptions)); if (NS_FAILED(rv)) { aRv.Throw(rv); @@ -1214,7 +1212,7 @@ Geolocation::GetCurrentPosition(PositionCallback& aCallback, NS_IMETHODIMP Geolocation::GetCurrentPosition(nsIDOMGeoPositionCallback* aCallback, nsIDOMGeoPositionErrorCallback* aErrorCallback, - idl::GeoPositionOptions* aOptions) + PositionOptions* aOptions) { NS_ENSURE_ARG_POINTER(aCallback); @@ -1227,7 +1225,7 @@ Geolocation::GetCurrentPosition(nsIDOMGeoPositionCallback* aCallback, nsresult Geolocation::GetCurrentPosition(GeoPositionCallback& callback, GeoPositionErrorCallback& errorCallback, - idl::GeoPositionOptions *options) + PositionOptions *options) { if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) { return NS_ERROR_NOT_AVAILABLE; @@ -1289,9 +1287,8 @@ Geolocation::WatchPosition(PositionCallback& aCallback, GeoPositionCallback successCallback(&aCallback); GeoPositionErrorCallback errorCallback(aErrorCallback); - nsresult rv = - WatchPosition(successCallback, errorCallback, - GeoPositionOptionsFromPositionOptions(aOptions), &ret); + nsresult rv = WatchPosition(successCallback, errorCallback, + CreatePositionOptionsCopy(aOptions), &ret); if (NS_FAILED(rv)) { aRv.Throw(rv); @@ -1303,7 +1300,7 @@ Geolocation::WatchPosition(PositionCallback& aCallback, NS_IMETHODIMP Geolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback, nsIDOMGeoPositionErrorCallback *aErrorCallback, - idl::GeoPositionOptions *aOptions, + PositionOptions *aOptions, int32_t* aRv) { NS_ENSURE_ARG_POINTER(aCallback); @@ -1317,7 +1314,7 @@ Geolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback, nsresult Geolocation::WatchPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, - idl::GeoPositionOptions* aOptions, + PositionOptions* aOptions, int32_t* aRv) { if (mWatchingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) { diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h index ce7be6d526e7..ec8bebebdf84 100644 --- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -176,8 +176,8 @@ private: ~Geolocation(); - nsresult GetCurrentPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, mozilla::idl::GeoPositionOptions* aOptions); - nsresult WatchPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, mozilla::idl::GeoPositionOptions* aOptions, int32_t* aRv); + nsresult GetCurrentPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, PositionOptions* aOptions); + nsresult WatchPosition(GeoPositionCallback& aCallback, GeoPositionErrorCallback& aErrorCallback, PositionOptions* aOptions, int32_t* aRv); bool RegisterRequestWithPrompt(nsGeolocationRequest* request); diff --git a/js/xpconnect/src/dictionary_helper_gen.conf b/js/xpconnect/src/dictionary_helper_gen.conf index ee90cdddc9ea..dc2bb55c9c93 100644 --- a/js/xpconnect/src/dictionary_helper_gen.conf +++ b/js/xpconnect/src/dictionary_helper_gen.conf @@ -4,7 +4,6 @@ # Dictionary interface name, interface file name dictionaries = [ - [ 'GeoPositionOptions', 'nsIDOMGeoGeolocation.idl' ], [ 'DOMFileMetadataParameters', 'nsIDOMLockedFile.idl' ], [ 'CameraSize', 'nsIDOMCameraManager.idl' ], [ 'CameraRegion', 'nsIDOMCameraManager.idl' ], From 89a2cfebf91748bdc1dc1182706e0b2410b725d2 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 6 Sep 2013 13:59:58 -0700 Subject: [PATCH 24/36] (no bug) Broaden fuzzy-if() annotation slightly, for reftest position-sticky/top-2.html. r=corey --- layout/reftests/position-sticky/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/position-sticky/reftest.list b/layout/reftests/position-sticky/reftest.list index 098c9a667f9e..3166a4d247f7 100644 --- a/layout/reftests/position-sticky/reftest.list +++ b/layout/reftests/position-sticky/reftest.list @@ -3,7 +3,7 @@ test-pref(layout.css.sticky.enabled,true) == pref-1.html pref-1-enabled-ref.html default-preferences pref(layout.css.sticky.enabled,true) == top-1.html top-1-ref.html -fuzzy-if(Android,4,914) == top-2.html top-2-ref.html +fuzzy-if(Android,6,914) == top-2.html top-2-ref.html fuzzy-if(Android,4,2729) == top-3.html top-3-ref.html == top-4.html top-4-ref.html == top-5.html top-5-ref.html From b21c464f8e5fdfb94dc8200311340e02dbc50d42 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 6 Sep 2013 17:05:25 -0400 Subject: [PATCH 25/36] Backed out changeset 45c336307136 (bug 910845) for bustage. --- js/src/gc/Memory.cpp | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/js/src/gc/Memory.cpp b/js/src/gc/Memory.cpp index 96b5edc8dab1..cb065942e682 100644 --- a/js/src/gc/Memory.cpp +++ b/js/src/gc/Memory.cpp @@ -309,40 +309,6 @@ gc::InitMemorySubsystem(JSRuntime *rt) rt->gcSystemPageSize = rt->gcSystemAllocGranularity = size_t(sysconf(_SC_PAGESIZE)); } -static inline void * -gc::MapMemory(size_t length, int prot, int flags, int fd, off_t offset) -{ -#if defined(__ia64__) - /* - * The JS engine assumes that all allocated pointers have their high 17 bits clear, - * which ia64's mmap doesn't support directly. However, we can emulate it by passing - * mmap an "addr" parameter with those bits clear. The mmap will return that address, - * or the nearest available memory above that address, providing a near-guarantee - * that those bits are clear. If they are not, we return NULL below to indicate - * out-of-memory. - * - * The addr is chosen as 0x0000070000000000, which still allows about 120TB of virtual - * address space. - * - * See Bug 589735 for more information. - */ - void *region = mmap((void*)0x0000070000000000, length, prot, flags, fd, offset); - if (region == MAP_FAILED) - return MAP_FAILED; - /* - * If the allocated memory doesn't have its upper 17 bits clear, consider it - * as out of memory. - */ - if ((uintptr_t(region) + (length - 1)) & 0xffff800000000000) { - JS_ALWAYS_TRUE(0 == munmap(region, length)); - return MAP_FAILED; - } - return region; -#else - return mmap(NULL, length, prot, flags, fd, offset); -#endif -} - void * gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment) { @@ -356,15 +322,12 @@ gc::MapAlignedPages(JSRuntime *rt, size_t size, size_t alignment) /* Special case: If we want page alignment, no further work is needed. */ if (alignment == rt->gcSystemAllocGranularity) { - void *region = MapMemory(size, prot, flags, -1, 0); - if (region == MAP_FAILED) - return NULL; - return region; + return mmap(NULL, size, prot, flags, -1, 0); } /* Overallocate and unmap the region's edges. */ size_t reqSize = Min(size + 2 * alignment, 2 * size); - void *region = MapMemory(reqSize, prot, flags, -1, 0); + void *region = mmap(NULL, reqSize, prot, flags, -1, 0); if (region == MAP_FAILED) return NULL; From 6b59c7963a25b69a4118343e189dedeb05d49c13 Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Tue, 27 Aug 2013 07:40:22 -0700 Subject: [PATCH 26/36] Bug 844071 - Patch 1 - handle building and parsing of setup and connection attributes r=abr --- .../signaling/src/sipcc/core/gsm/gsm_sdp.c | 110 ++++++++++++ .../signaling/src/sipcc/core/gsm/h/fsm.h | 5 + .../webrtc/signaling/src/sipcc/core/sdp/sdp.h | 27 +++ .../signaling/src/sipcc/core/sdp/sdp_attr.c | 124 ++++++++++++++ .../src/sipcc/core/sdp/sdp_attr_access.c | 157 ++++++++++++++++++ .../signaling/src/sipcc/core/sdp/sdp_main.c | 21 ++- .../src/sipcc/core/sdp/sdp_private.h | 14 ++ .../signaling/src/sipcc/include/ccsdp.h | 13 ++ 8 files changed, 470 insertions(+), 1 deletion(-) diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c index 892e9d8b9388..bc88de67834e 100644 --- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c @@ -528,6 +528,9 @@ gsmsdp_init_media (fsmdef_media_t *media) media->candidate_ct = 0; media->rtcp_mux = FALSE; + /* ACTPASS is the value we put in every offer */ + media->setup = SDP_SETUP_ACTPASS; + media->local_datachannel_port = 0; media->remote_datachannel_port = 0; media->datachannel_streams = WEBRTC_DATACHANNEL_STREAMS_DEFAULT; @@ -1821,6 +1824,71 @@ gsmsdp_set_rtcp_mux_attribute (sdp_attr_e sdp_attr, uint16_t level, void *sdp_p, } } +/* + * gsmsdp_set_setup_attribute + * + * Description: + * + * Adds a setup attribute to the specified SDP. + * + * Parameters: + * + * level - The media level of the SDP where the media attribute exists. + * sdp_p - Pointer to the SDP to set the ice candidate attribute against. + * setup_type - Value for the a=setup line + */ +static void +gsmsdp_set_setup_attribute(uint16_t level, + void *sdp_p, sdp_setup_type_e setup_type) { + uint16_t a_instance = 0; + sdp_result_e result; + + result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_SETUP, &a_instance); + if (result != SDP_SUCCESS) { + GSM_ERR_MSG("Failed to add attribute"); + return; + } + + result = sdp_attr_set_setup_attribute(sdp_p, level, 0, + a_instance, setup_type); + if (result != SDP_SUCCESS) { + GSM_ERR_MSG("Failed to set attribute"); + } +} + +/* + * gsmsdp_set_connection_attribute + * + * Description: + * + * Adds a connection attribute to the specified SDP. + * + * Parameters: + * + * level - The media level of the SDP where the media attribute exists. + * sdp_p - Pointer to the SDP to set the ice candidate attribute against. + * connection_type - Value for the a=connection line + */ +static void +gsmsdp_set_connection_attribute(uint16_t level, + void *sdp_p, sdp_connection_type_e connection_type) { + uint16_t a_instance = 0; + sdp_result_e result; + + result = sdp_add_new_attr(sdp_p, level, 0, SDP_ATTR_CONNECTION, + &a_instance); + if (result != SDP_SUCCESS) { + GSM_ERR_MSG("Failed to add attribute"); + return; + } + + result = sdp_attr_set_connection_attribute(sdp_p, level, 0, + a_instance, connection_type); + if (result != SDP_SUCCESS) { + GSM_ERR_MSG("Failed to set attribute"); + } +} + /* * gsmsdp_set_dtls_fingerprint_attribute * @@ -4641,6 +4709,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial sdp_result_e sdp_res; boolean created_media_stream = FALSE; int lsm_rc; + sdp_setup_type_e remote_setup_type; config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); @@ -4939,6 +5008,40 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial if (sdpmode) { int j; + /* Find the remote a=setup value */ + sdp_res = sdp_attr_get_setup_attribute( + sdp_p->dest_sdp, i, 0, 1, &remote_setup_type); + + + /* setup attribute + We are setting our local SDP to be ACTIVE if the value + in the remote SDP is missing, PASSIVE or ACTPASS. + If the remote value is ACTIVE, then we will respond + with PASSIVE. + If the remote value is HOLDCONN we will respond with + HOLDCONN and set the direction to INACTIVE + The DTLS role will then be set when the TransportFlow + is created */ + media->setup = SDP_SETUP_ACTIVE; + + if (sdp_res == SDP_SUCCESS) { + if (remote_setup_type == SDP_SETUP_ACTIVE) { + media->setup = SDP_SETUP_PASSIVE; + } else if (remote_setup_type == SDP_SETUP_HOLDCONN) { + media->setup = SDP_SETUP_HOLDCONN; + media->direction = SDP_DIRECTION_INACTIVE; + } + } + + gsmsdp_set_setup_attribute(media->level, dcb_p->sdp->src_sdp, + media->setup); + + /* TODO(ehugg) we are not yet supporting existing connections + See bug 857115. We currently always respond with + connection:new */ + gsmsdp_set_connection_attribute(media->level, + dcb_p->sdp->src_sdp, SDP_CONNECTION_NEW); + /* Set ICE */ for (j=0; jcandidate_ct; j++) { gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, media->level, @@ -5456,6 +5559,13 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, SDP_RTCP_FB_CCM_TO_BITMAP(SDP_RTCP_FB_CCM_FIR)); } + /* setup and connection attributes */ + gsmsdp_set_setup_attribute(level, dcb_p->sdp->src_sdp, media->setup); + + /* This is a new media line so we should send connection:new */ + gsmsdp_set_connection_attribute(level, dcb_p->sdp->src_sdp, + SDP_CONNECTION_NEW); + /* * wait until here to set ICE candidates as SDP is now initialized */ diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h index 85a72abbedca..862273de85fc 100755 --- a/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h +++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/fsm.h @@ -207,6 +207,11 @@ typedef struct fsmdef_media_t_ { */ boolean rtcp_mux; + /* + * The value of the a=setup line + */ + sdp_setup_type_e setup; + /* * port number used in m= data channel line */ diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h b/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h index cda4b552625b..3f6a1042ea9c 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h @@ -519,6 +519,14 @@ typedef enum { SDP_RTCP_FB_CCM_UNKNOWN } sdp_rtcp_fb_ccm_type_e; +typedef enum { + SDP_CONNECTION_NOT_FOUND = -1, + SDP_CONNECTION_NEW = 0, + SDP_CONNECTION_EXISTING, + SDP_MAX_CONNECTION, + SDP_CONNECTION_UNKNOWN +} sdp_connection_type_e; + #define SDP_RTCP_FB_NACK_TO_BITMAP(type) (1 << (type)) #define SDP_RTCP_FB_ACK_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + (type))) #define SDP_RTCP_FB_CCM_TO_BITMAP(type) (1 << (SDP_MAX_RTCP_FB_NACK + \ @@ -1017,6 +1025,8 @@ typedef struct sdp_attr { char unknown[SDP_MAX_STRING_LEN+1]; sdp_source_filter_t source_filter; sdp_fmtp_fb_t rtcp_fb; + sdp_setup_type_e setup; + sdp_connection_type_e connection; } attr; struct sdp_attr *next_p; } sdp_attr_t; @@ -2069,6 +2079,23 @@ sdp_result_e sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level, u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, const tinybool rtcp_mux); + +sdp_result_e +sdp_attr_get_setup_attribute (void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_setup_type_e *setup_type); + +sdp_result_e +sdp_attr_set_setup_attribute(void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_setup_type_e setup_type); + +sdp_result_e +sdp_attr_get_connection_attribute (void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_connection_type_e *connection_type); + +sdp_result_e +sdp_attr_set_connection_attribute(void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_connection_type_e connection_type); + sdp_result_e sdp_attr_get_dtls_fingerprint_attribute (void *sdp_ptr, u16 level, u8 cap_num, sdp_attr_e sdp_attr, u16 inst_num, diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c index 808b162648c1..09e9cfb94339 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr.c @@ -4986,3 +4986,127 @@ sdp_result_e sdp_parse_attr_rtcp_fb (sdp_t *sdp_p, return SDP_SUCCESS; } + +sdp_result_e sdp_build_attr_setup(sdp_t *sdp_p, + sdp_attr_t *attr_p, + flex_string *fs) +{ + switch (attr_p->attr.setup) { + case SDP_SETUP_ACTIVE: + case SDP_SETUP_PASSIVE: + case SDP_SETUP_ACTPASS: + case SDP_SETUP_HOLDCONN: + flex_string_sprintf(fs, "a=%s:%s\r\n", + sdp_attr[attr_p->type].name, + sdp_setup_type_val[attr_p->attr.setup].name); + break; + default: + CSFLogError(logTag, "%s Error: Invalid setup enum (%d)", + sdp_p->debug_str, attr_p->attr.setup); + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + +sdp_result_e sdp_parse_attr_setup(sdp_t *sdp_p, + sdp_attr_t *attr_p, + const char *ptr) +{ + int i = find_token_enum("setup attribute", sdp_p, &ptr, + sdp_setup_type_val, + SDP_MAX_SETUP, SDP_SETUP_UNKNOWN); + + if (i < 0) { + sdp_parse_error(sdp_p->peerconnection, + "%s Warning: could not parse setup attribute", + sdp_p->debug_str); + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + attr_p->attr.setup = (sdp_setup_type_e) i; + + switch (attr_p->attr.setup) { + case SDP_SETUP_ACTIVE: + case SDP_SETUP_PASSIVE: + case SDP_SETUP_ACTPASS: + case SDP_SETUP_HOLDCONN: + /* All these values are OK */ + break; + case SDP_SETUP_UNKNOWN: + sdp_parse_error(sdp_p->peerconnection, + "%s Warning: Unknown setup attribute", + sdp_p->debug_str); + return SDP_INVALID_PARAMETER; + break; + default: + /* This is an internal error, not a parsing error */ + CSFLogError(logTag, "%s Error: Invalid setup enum (%d)", + sdp_p->debug_str, attr_p->attr.setup); + return SDP_FAILURE; + break; + } + + return SDP_SUCCESS; +} + +sdp_result_e sdp_build_attr_connection(sdp_t *sdp_p, + sdp_attr_t *attr_p, + flex_string *fs) +{ + switch (attr_p->attr.connection) { + case SDP_CONNECTION_NEW: + case SDP_CONNECTION_EXISTING: + flex_string_sprintf(fs, "a=%s:%s\r\n", + sdp_attr[attr_p->type].name, + sdp_connection_type_val[attr_p->attr.connection].name); + break; + default: + CSFLogError(logTag, "%s Error: Invalid connection enum (%d)", + sdp_p->debug_str, attr_p->attr.connection); + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + +sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p, + sdp_attr_t *attr_p, + const char *ptr) +{ + int i = find_token_enum("connection attribute", sdp_p, &ptr, + sdp_connection_type_val, + SDP_MAX_CONNECTION, SDP_CONNECTION_UNKNOWN); + + if (i < 0) { + sdp_parse_error(sdp_p->peerconnection, + "%s Warning: could not parse connection attribute", + sdp_p->debug_str); + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + attr_p->attr.connection = (sdp_connection_type_e) i; + + switch (attr_p->attr.connection) { + case SDP_CONNECTION_NEW: + case SDP_CONNECTION_EXISTING: + /* All these values are OK */ + break; + case SDP_CONNECTION_UNKNOWN: + sdp_parse_error(sdp_p->peerconnection, + "%s Warning: Unknown connection attribute", + sdp_p->debug_str); + return SDP_INVALID_PARAMETER; + break; + default: + /* This is an internal error, not a parsing error */ + CSFLogError(logTag, "%s Error: Invalid connection enum (%d)", + sdp_p->debug_str, attr_p->attr.connection); + return SDP_FAILURE; + break; + } + + return SDP_SUCCESS; +} diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c index d37cde798cd1..886a915d11cf 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_attr_access.c @@ -4084,6 +4084,163 @@ sdp_result_e sdp_attr_set_rtcp_mux_attribute(void *sdp_ptr, u16 level, return (SDP_SUCCESS); } + +/* Function: sdp_attr_get_setup_attribute + * Description: Returns the value of a setup attribute at a given level + * + * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. + * level The level to check for the attribute. + * cap_num The capability number associated with the + * attribute if any. If none, should be zero. + * inst_num The attribute instance number to check. + * setup_type Returns sdp_setup_type_e enum + * Returns: + * SDP_SUCCESS Attribute param was set successfully. + * SDP_INVALID_SDP_PTR SDP pointer invalid + * SDP_INVALID_PARAMETER Specified attribute is not defined. + */ +sdp_result_e sdp_attr_get_setup_attribute (void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_setup_type_e *setup_type) +{ + sdp_t *sdp_p = (sdp_t *)sdp_ptr; + sdp_attr_t *attr_p; + + if (!sdp_verify_sdp_ptr(sdp_p)) { + return SDP_INVALID_SDP_PTR; + } + + attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SETUP, inst_num); + if (!attr_p) { + if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + CSFLogError(logTag, + "%s setup attribute, level %u instance %u not found.", + sdp_p->debug_str, level, inst_num); + } + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + *setup_type = attr_p->attr.setup; + return SDP_SUCCESS; +} + +/* Function: sdp_attr_set_setup_attribute + * Description: Sets the value of a setup attribute parameter + * + * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. + * level The level to set the attribute. + * cap_num The capability number associated with the + * attribute if any. If none, should be zero. + * inst_num The attribute instance number to check. + * setup_type setup attribute value to set + * Returns: SDP_SUCCESS Attribute param was set successfully. + * SDP_INVALID_SDP_PTR SDP ptr invalid + * SDP_INVALID_PARAMETER Specified attribute is not defined. + */ +sdp_result_e +sdp_attr_set_setup_attribute(void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_setup_type_e setup_type) +{ + sdp_t *sdp_p = (sdp_t *)sdp_ptr; + sdp_attr_t *attr_p; + + if (!sdp_verify_sdp_ptr(sdp_p)) { + return SDP_INVALID_SDP_PTR; + } + + attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_SETUP, inst_num); + if (!attr_p) { + if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + CSFLogError(logTag, "%s setup attribute, level %u instance %u " + "not found.", sdp_p->debug_str, level, inst_num); + } + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + attr_p->attr.setup = setup_type; + return SDP_SUCCESS; +} + +/* Function: sdp_attr_get_connection_attribute + * Description: Returns the value of a connection attribute at a given level + * + * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. + * level The level to check for the attribute. + * cap_num The capability number associated with the + * attribute if any. If none, should be zero. + * inst_num The attribute instance number to check. + * connection_type Returns sdp_connection_type_e enum + * Returns: + * SDP_SUCCESS Attribute param was set successfully. + * SDP_INVALID_SDP_PTR SDP pointer invalid + * SDP_INVALID_PARAMETER Specified attribute is not defined. + */ +sdp_result_e sdp_attr_get_connection_attribute (void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_connection_type_e *connection_type) +{ + sdp_t *sdp_p = (sdp_t *)sdp_ptr; + sdp_attr_t *attr_p; + + if (!sdp_verify_sdp_ptr(sdp_p)) { + return SDP_INVALID_SDP_PTR; + } + + attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_CONNECTION, + inst_num); + if (!attr_p) { + if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + CSFLogError(logTag, + "%s setup attribute, level %u instance %u not found.", + sdp_p->debug_str, level, inst_num); + } + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + *connection_type = attr_p->attr.connection; + return SDP_SUCCESS; +} + +/* Function: sdp_attr_set_connection_attribute + * Description: Sets the value of a connection attribute parameter + * + * Parameters: sdp_ptr The SDP handle returned by sdp_init_description. + * level The level to set the attribute. + * cap_num The capability number associated with the + * attribute if any. If none, should be zero. + * inst_num The attribute instance number to check. + * connection_type connection attribute value to set + * Returns: SDP_SUCCESS Attribute param was set successfully. + * SDP_INVALID_SDP_PTR SDP ptr invalid + * SDP_INVALID_PARAMETER Specified attribute is not defined. + */ +sdp_result_e +sdp_attr_set_connection_attribute(void *sdp_ptr, u16 level, + u8 cap_num, u16 inst_num, sdp_connection_type_e connection_type) +{ + sdp_t *sdp_p = (sdp_t *)sdp_ptr; + sdp_attr_t *attr_p; + + if (!sdp_verify_sdp_ptr(sdp_p)) { + return SDP_INVALID_SDP_PTR; + } + + attr_p = sdp_find_attr(sdp_p, level, cap_num, SDP_ATTR_CONNECTION, + inst_num); + if (!attr_p) { + if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) { + CSFLogError(logTag, "%s connection attribute, level %u instance %u " + "not found.", sdp_p->debug_str, level, inst_num); + } + sdp_p->conf_p->num_invalid_param++; + return SDP_INVALID_PARAMETER; + } + + attr_p->attr.connection = connection_type; + return SDP_SUCCESS; +} + /* Function: sdp_attr_get_dtls_fingerprint_attribute * Description: Returns the value of dtls fingerprint attribute at a given level * diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c index 1c1ff7c0b353..0ecf1da42d38 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_main.c @@ -169,7 +169,11 @@ const sdp_attrarray_t sdp_attr[SDP_MAX_ATTR_TYPES] = {"maxptime", sizeof("maxptime"), sdp_parse_attr_simple_u32, sdp_build_attr_simple_u32}, {"rtcp-fb", sizeof("rtcp-fb"), - sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb} + sdp_parse_attr_rtcp_fb, sdp_build_attr_rtcp_fb}, + {"setup", sizeof("setup"), + sdp_parse_attr_setup, sdp_build_attr_setup}, + {"connection", sizeof("connection"), + sdp_parse_attr_connection, sdp_build_attr_connection}, }; /* Note: These *must* be in the same order as the enum types. */ @@ -483,6 +487,21 @@ const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[SDP_MAX_RTCP_FB_CCM] = SDP_NAME("vbcm") }; +/* Maintain the same order as defined in typedef sdp_setup_type_e */ +const sdp_namearray_t sdp_setup_type_val[SDP_MAX_SETUP] = +{ + SDP_NAME("active"), + SDP_NAME("passive"), + SDP_NAME("actpass"), + SDP_NAME("holdconn") +}; + +/* Maintain the same order as defined in typedef sdp_connection_type_e */ +const sdp_namearray_t sdp_connection_type_val[SDP_MAX_CONNECTION] = +{ + SDP_NAME("new"), + SDP_NAME("existing") +}; /* Maintain same order as defined in typedef sdp_srtp_crypto_suite_t */ const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[SDP_SRTP_MAX_NUM_CRYPTO_SUITES] = diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h index 8f6e6a7bf642..ac6cf0f96de5 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_private.h @@ -37,6 +37,8 @@ extern const sdp_namearray_t sdp_rtcp_fb_type_val[]; extern const sdp_namearray_t sdp_rtcp_fb_nack_type_val[]; extern const sdp_namearray_t sdp_rtcp_fb_ack_type_val[]; extern const sdp_namearray_t sdp_rtcp_fb_ccm_type_val[]; +extern const sdp_namearray_t sdp_setup_type_val[]; +extern const sdp_namearray_t sdp_connection_type_val[]; extern const sdp_srtp_crypto_suite_list sdp_srtp_crypto_suite_array[]; @@ -149,6 +151,18 @@ extern sdp_result_e sdp_parse_attr_rtcp_fb(sdp_t *sdp_p, extern sdp_result_e sdp_build_attr_rtcp_fb(sdp_t *sdp_p, sdp_attr_t *attr_p, flex_string *fs); +extern sdp_result_e sdp_parse_attr_setup(sdp_t *sdp_p, + sdp_attr_t *attr_p, + const char *ptr); +extern sdp_result_e sdp_build_attr_setup(sdp_t *sdp_p, + sdp_attr_t *attr_p, + flex_string *fs); +extern sdp_result_e sdp_parse_attr_connection(sdp_t *sdp_p, + sdp_attr_t *attr_p, + const char *ptr); +extern sdp_result_e sdp_build_attr_connection(sdp_t *sdp_p, + sdp_attr_t *attr_p, + flex_string *fs); extern sdp_result_e sdp_parse_attr_mptime( sdp_t *sdp_p, sdp_attr_t *attr_p, const char *ptr); extern sdp_result_e sdp_build_attr_mptime( diff --git a/media/webrtc/signaling/src/sipcc/include/ccsdp.h b/media/webrtc/signaling/src/sipcc/include/ccsdp.h index dc7ca1b0bc1c..e424b9c1088e 100644 --- a/media/webrtc/signaling/src/sipcc/include/ccsdp.h +++ b/media/webrtc/signaling/src/sipcc/include/ccsdp.h @@ -242,10 +242,23 @@ typedef enum { SDP_ATTR_DTLS_FINGERPRINT, SDP_ATTR_MAXPTIME, SDP_ATTR_RTCP_FB, /* RFC 4585 */ + SDP_ATTR_SETUP, + SDP_ATTR_CONNECTION, SDP_MAX_ATTR_TYPES, SDP_ATTR_INVALID } sdp_attr_e; +/* This is here so that it can be used in the VcmSIPCCBinding interface */ +typedef enum { + SDP_SETUP_NOT_FOUND = -1, + SDP_SETUP_ACTIVE = 0, + SDP_SETUP_PASSIVE, + SDP_SETUP_ACTPASS, + SDP_SETUP_HOLDCONN, + SDP_MAX_SETUP, + SDP_SETUP_UNKNOWN +} sdp_setup_type_e; + /** * Gets the value of the fmtp attribute- parameter-sets parameter for H.264 codec * From 18ea3a26f8f4d7da15452576f6f651f7f28ae6fe Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Tue, 27 Aug 2013 07:53:24 -0700 Subject: [PATCH 27/36] Bug 844071 - Patch 2 - Reset DTLS role on SDP negotiation r=ekr --- .../signaling/src/media/VcmSIPCCBinding.cpp | 49 ++++++++++++------- .../src/peerconnection/PeerConnectionImpl.cpp | 5 -- .../src/peerconnection/PeerConnectionImpl.h | 14 ------ .../webrtc/signaling/src/sipcc/core/gsm/lsm.c | 2 + .../webrtc/signaling/src/sipcc/include/vcm.h | 4 ++ 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp index 0ab6ee077408..53af816c1be7 100644 --- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp +++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp @@ -69,11 +69,13 @@ int VcmSIPCCBinding::gAudioCodecMask = 0; int VcmSIPCCBinding::gVideoCodecMask = 0; nsIThread *VcmSIPCCBinding::gMainThread = NULL; -static mozilla::RefPtr vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc, - int level, bool rtcp, - const char *fingerprint_alg, - const char *fingerprint - ); +static mozilla::RefPtr vcmCreateTransportFlow( + sipcc::PeerConnectionImpl *pc, + int level, + bool rtcp, + sdp_setup_type_e setup_type, + const char *fingerprint_alg, + const char *fingerprint); // Convenience macro to acquire PC @@ -1349,6 +1351,7 @@ int vcmRxStart(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] num_payloads - number of negotiated payloads * @param[in] payloads - negotiated codec details list + * @param[in] setup - whether playing client or server role * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -1366,6 +1369,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, const char *peerconnection, int num_payloads, const vcm_payload_info_t* payloads, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs) @@ -1378,7 +1382,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, // Datachannel will use this though not for RTP mozilla::RefPtr rtp_flow = - vcmCreateTransportFlow(pc.impl(), level, false, + vcmCreateTransportFlow(pc.impl(), level, false, setup_type, fingerprint_alg, fingerprint); if (!rtp_flow) { CSFLogError( logTag, "Could not create RTP flow"); @@ -1407,7 +1411,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, mozilla::RefPtr rtcp_flow = nullptr; if(!attrs->rtcp_mux) { - rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, + rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, setup_type, fingerprint_alg, fingerprint); if (!rtcp_flow) { CSFLogError( logTag, "Could not create RTCP flow"); @@ -1535,6 +1539,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] num_payloads - number of negotiated payloads * @param[in] payloads - negotiated codec details list + * @param[in] setup_type - whether playing client or server role * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -1552,6 +1557,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id, const char *peerconnection, int num_payloads, const vcm_payload_info_t* payloads, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs) @@ -1570,6 +1576,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id, peerconnection, num_payloads, payloads, + setup_type, fingerprint_alg, fingerprint, attrs, @@ -2009,6 +2016,7 @@ int vcmTxStart(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] payload - payload information * @param[in] tos - bit marking + * @param[in] setup_type - whether playing the client or server role * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -2028,6 +2036,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, const char *peerconnection, const vcm_payload_info_t *payload, short tos, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs) @@ -2042,7 +2051,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, // Create the transport flows mozilla::RefPtr rtp_flow = - vcmCreateTransportFlow(pc.impl(), level, false, + vcmCreateTransportFlow(pc.impl(), level, false, setup_type, fingerprint_alg, fingerprint); if (!rtp_flow) { CSFLogError( logTag, "Could not create RTP flow"); @@ -2050,7 +2059,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, } mozilla::RefPtr rtcp_flow = nullptr; if(!attrs->rtcp_mux) { - rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, + rtcp_flow = vcmCreateTransportFlow(pc.impl(), level, true, setup_type, fingerprint_alg, fingerprint); if (!rtcp_flow) { CSFLogError( logTag, "Could not create RTCP flow"); @@ -2166,6 +2175,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] payload - payload type * @param[in] tos - bit marking + * @param[in] setup_type - whether playing client or server role. * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -2185,6 +2195,7 @@ int vcmTxStartICE(cc_mcapid_t mcap_id, const char *peerconnection, const vcm_payload_info_t *payload, short tos, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs) @@ -2203,6 +2214,7 @@ int vcmTxStartICE(cc_mcapid_t mcap_id, peerconnection, payload, tos, + setup_type, fingerprint_alg, fingerprint, attrs, @@ -2700,8 +2712,8 @@ int vcmGetILBCMode() static mozilla::RefPtr vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc, int level, bool rtcp, - const char *fingerprint_alg, - const char *fingerprint) { + sdp_setup_type_e setup_type, const char *fingerprint_alg, + const char *fingerprint) { // TODO(ekr@rtfm.com): Check that if the flow already exists the digest // is the same. The only way that can happen is if @@ -2743,13 +2755,14 @@ vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc, int level, bool rtcp, // party is active MUST initiate a DTLS handshake by sending a // ClientHello over each flow (host/port quartet). // - // Currently we just hardwire the roles to be that the offerer is the - // server, which is what you would expect from the "recommended" - // behavior above. - // - // TODO(ekr@rtfm.com): implement the actpass logic above. - dtls->SetRole(pc->GetRole() == sipcc::PeerConnectionImpl::kRoleOfferer ? - TransportLayerDtls::SERVER : TransportLayerDtls::CLIENT); + + // setup_type should at this point be either PASSIVE or ACTIVE + // other a=setup values should have been negotiated out. + MOZ_ASSERT(setup_type == SDP_SETUP_PASSIVE || + setup_type == SDP_SETUP_ACTIVE); + dtls->SetRole( + setup_type == SDP_SETUP_PASSIVE ? + TransportLayerDtls::SERVER : TransportLayerDtls::CLIENT); mozilla::RefPtr pcid = pc->GetIdentity(); if (!pcid) { return nullptr; diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp index 6855d38570b6..9dc5158acc15 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp @@ -335,7 +335,6 @@ NS_IMPL_ISUPPORTS1(PeerConnectionImpl, IPeerConnection) PeerConnectionImpl::PeerConnectionImpl() : mTimeCard(PR_LOG_TEST(signalingLogInfo(),PR_LOG_ERROR) ? create_timecard() : nullptr) - , mRole(kRoleUnknown) , mCall(NULL) , mReadyState(kNew) , mSignalingState(kSignalingStable) @@ -1022,8 +1021,6 @@ PeerConnectionImpl::CreateOffer(MediaConstraints& constraints) mTimeCard = nullptr; STAMP_TIMECARD(tc, "Create Offer"); - mRole = kRoleOfferer; // TODO(ekr@rtfm.com): Interrogate SIPCC here? - cc_media_constraints_t* cc_constraints = nullptr; constraints.buildArray(&cc_constraints); @@ -1054,8 +1051,6 @@ PeerConnectionImpl::CreateAnswer(MediaConstraints& constraints) mTimeCard = nullptr; STAMP_TIMECARD(tc, "Create Answer"); - mRole = kRoleAnswerer; // TODO(ekr@rtfm.com): Interrogate SIPCC here? - cc_media_constraints_t* cc_constraints = nullptr; constraints.buildArray(&cc_constraints); diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h index 36e75d66452d..ba058538c9dc 100644 --- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h +++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h @@ -165,12 +165,6 @@ public: kIceFailed }; - enum Role { - kRoleUnknown, - kRoleOfferer, - kRoleAnswerer - }; - enum Error { kNoError = 0, kInvalidConstraintsType = 1, @@ -195,11 +189,6 @@ public: static already_AddRefed MakeMediaStream(nsPIDOMWindow* aWindow, uint32_t aHint); - Role GetRole() const { - PC_AUTO_ENTER_API_CALL_NO_CHECK(); - return mRole; - } - nsresult CreateRemoteSourceStreamInfo(nsRefPtr* aInfo); // Implementation of the only observer we need @@ -339,9 +328,6 @@ private: // any other attributes of this class. Timecard *mTimeCard; - // The role we are adopting - Role mRole; - // The call CSF::CC_CallPtr mCall; ReadyState mReadyState; diff --git a/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c b/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c index 3019f8884ec4..0bd143366621 100755 --- a/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/lsm.c @@ -1006,6 +1006,7 @@ lsm_rx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) dcb->peerconnection, media->num_payloads, media->payloads, + media->setup, FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), FSM_NEGOTIATED_CRYPTO_DIGEST(media), &attrs); @@ -1276,6 +1277,7 @@ lsm_tx_start (lsm_lcb_t *lcb, const char *fname, fsmdef_media_t *media) dcb->peerconnection, media->payloads, (short)dscp, + media->setup, FSM_NEGOTIATED_CRYPTO_DIGEST_ALGORITHM(media), FSM_NEGOTIATED_CRYPTO_DIGEST(media), &attrs) == -1) diff --git a/media/webrtc/signaling/src/sipcc/include/vcm.h b/media/webrtc/signaling/src/sipcc/include/vcm.h index aa1266c92e98..f9a4e858521a 100755 --- a/media/webrtc/signaling/src/sipcc/include/vcm.h +++ b/media/webrtc/signaling/src/sipcc/include/vcm.h @@ -585,6 +585,7 @@ int vcmRxStart(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] num_payloads - number of codecs negotiated * @param[in] payloads - list of negotiated codec details + * @param[in] setup_t - whether playing client or server role * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -603,6 +604,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id, const char *peerconnection, int num_payloads, const vcm_payload_info_t* payloads, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs); @@ -663,6 +665,7 @@ int vcmTxStart(cc_mcapid_t mcap_id, * @param[in] peerconnection - the peerconnection in use * @param[in] payload - payload information * @param[in] tos - bit marking + * @param[in] setup_type - whether playing client or server role * @param[in] fingerprint_alg - the DTLS fingerprint algorithm * @param[in] fingerprint - the DTLS fingerprint * @param[in] attrs - media attributes @@ -681,6 +684,7 @@ int vcmTxStart(cc_mcapid_t mcap_id, const char *peerconnection, const vcm_payload_info_t *payload, short tos, + sdp_setup_type_e setup_type, const char *fingerprint_alg, const char *fingerprint, vcm_mediaAttrs_t *attrs); From 7e93bc05308c0e21930b75b5a2f47fede99499b8 Mon Sep 17 00:00:00 2001 From: Ethan Hugg Date: Mon, 26 Aug 2013 21:55:43 -0700 Subject: [PATCH 28/36] Bug 844071 - Patch 3 - DTLS role negotiation unit test r=ekr --- .../signaling/test/signaling_unittests.cpp | 346 ++++++++++++++++++ 1 file changed, 346 insertions(+) diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index 3755a1c6e05d..14f178b57258 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -2472,6 +2472,352 @@ TEST_F(SignalingTest, FullCallAudioNoMuxVideoMux) PIPELINE_VIDEO); } +// In this test we will change the offer SDP's a=setup value +// from actpass to passive. This will make the answer do active. +TEST_F(SignalingTest, AudioCallForceDtlsRoles) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give actpass + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + // Now replace the actpass with passive so that the answer will + // return active + offer.replace(match, strlen("\r\na=setup:actpass"), + "\r\na=setup:passive"); + std::cout << "Modified SDP " << std::endl + << indent(offer) << std::endl; + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:active + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:active"); + ASSERT_NE(match, std::string::npos); + + // This should setup the DTLS with the same roles + // as the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + +// In this test we will change the offer SDP's a=setup value +// from actpass to active. This will make the answer do passive +TEST_F(SignalingTest, AudioCallReverseDtlsRoles) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give actpass + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + // Now replace the actpass with active so that the answer will + // return passive + offer.replace(match, strlen("\r\na=setup:actpass"), + "\r\na=setup:active"); + std::cout << "Modified SDP " << std::endl + << indent(offer) << std::endl; + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:passive + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:passive"); + ASSERT_NE(match, std::string::npos); + + // This should setup the DTLS with the opposite roles + // than the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + +// In this test we will change the answer SDP's a=setup value +// from active to passive. This will make both sides do +// active and should not connect. +TEST_F(SignalingTest, AudioCallMismatchDtlsRoles) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give actpass + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:active + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:active"); + ASSERT_NE(match, std::string::npos); + + // Now replace the active with passive so that the offerer will + // also do active. + answer.replace(match, strlen("\r\na=setup:active"), + "\r\na=setup:passive"); + std::cout << "Modified SDP " << std::endl + << indent(answer) << std::endl; + + // This should setup the DTLS with both sides playing active + a2_.SetLocal(TestObserver::ANSWER, answer.c_str(), false); + a1_.SetRemote(TestObserver::ANSWER, answer.c_str(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Not using ASSERT_TRUE_WAIT here because we expect failure + PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + // In this case we should receive nothing. + ASSERT_EQ(a2_.GetPacketsReceived(0), 0); +} + +// In this test we will change the offer SDP's a=setup value +// from actpass to garbage. It should ignore the garbage value +// and respond with setup:active +TEST_F(SignalingTest, AudioCallGarbageSetup) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give actpass + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + // Now replace the actpass with a garbage value + offer.replace(match, strlen("\r\na=setup:actpass"), + "\r\na=setup:G4rb4g3V4lu3"); + std::cout << "Modified SDP " << std::endl + << indent(offer) << std::endl; + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:active + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:active"); + ASSERT_NE(match, std::string::npos); + + // This should setup the DTLS with the same roles + // as the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + +// In this test we will change the offer SDP's a=connection value +// from new to garbage. It should ignore the garbage value +// and respond with connection:new +TEST_F(SignalingTest, AudioCallGarbageConnection) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give connection:new + std::string offer(a1_.offer()); + match = offer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + // Now replace the 'new' with a garbage value + offer.replace(match, strlen("\r\na=connection:new"), + "\r\na=connection:G4rb4g3V4lu3"); + std::cout << "Modified SDP " << std::endl + << indent(offer) << std::endl; + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=connection:new + std::string answer(a2_.answer()); + match = answer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + + // This should setup the DTLS with the same roles + // as the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + +// In this test we will change the offer SDP to remove the +// a=setup and a=connection lines. Answer should respond with +// a=setup:active and a=connection:new +TEST_F(SignalingTest, AudioCallOfferNoSetupOrConnection) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give setup:actpass and connection:new + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + // Remove the a=setup line + offer.replace(match, strlen("\r\na=setup:actpass"), ""); + match = offer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + // Remove the a=connection line + offer.replace(match, strlen("\r\na=connection:new"), ""); + std::cout << "Modified SDP " << std::endl + << indent(offer) << std::endl; + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:active and a=connection:new + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:active"); + ASSERT_NE(match, std::string::npos); + match = answer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + + // This should setup the DTLS with the same roles + // as the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + +// In this test we will change the answer SDP to remove the +// a=setup and a=connection lines. ICE should still connect +// since active will be assumed. +TEST_F(SignalingTest, AudioCallAnswerNoSetupOrConnection) +{ + sipcc::MediaConstraints constraints; + size_t match; + + a1_.CreateOffer(constraints, OFFER_AUDIO, SHOULD_SENDRECV_AUDIO); + + // By default the offer should give setup:actpass and connection:new + std::string offer(a1_.offer()); + match = offer.find("\r\na=setup:actpass"); + ASSERT_NE(match, std::string::npos); + match = offer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + + a1_.SetLocal(TestObserver::OFFER, offer.c_str(), false); + a2_.SetRemote(TestObserver::OFFER, offer.c_str(), false); + a2_.CreateAnswer(constraints, offer.c_str(), OFFER_AUDIO | ANSWER_AUDIO); + + // Now the answer should contain a=setup:active and a=connection:new + std::string answer(a2_.answer()); + match = answer.find("\r\na=setup:active"); + ASSERT_NE(match, std::string::npos); + // Remove the a=setup line + answer.replace(match, strlen("\r\na=setup:active"), ""); + match = answer.find("\r\na=connection:new"); + ASSERT_NE(match, std::string::npos); + // Remove the a=connection line + answer.replace(match, strlen("\r\na=connection:new"), ""); + std::cout << "Modified SDP " << std::endl + << indent(answer) << std::endl; + + // This should setup the DTLS with the same roles + // as the regular tests above. + a2_.SetLocal(TestObserver::ANSWER, a2_.answer(), false); + a1_.SetRemote(TestObserver::ANSWER, a2_.answer(), false); + + ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); + ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); + + // Wait for some data to get written + ASSERT_TRUE_WAIT(a1_.GetPacketsSent(0) >= 40 && + a2_.GetPacketsReceived(0) >= 40, kDefaultTimeout * 2); + + a1_.CloseSendStreams(); + a2_.CloseReceiveStreams(); + + ASSERT_GE(a1_.GetPacketsSent(0), 40); + ASSERT_GE(a2_.GetPacketsReceived(0), 40); +} + } // End namespace test. bool is_color_terminal(const char *terminal) { From 0e3aac408361e96aa7a39391945a41cfec6263b8 Mon Sep 17 00:00:00 2001 From: Brian Bondy Date: Fri, 6 Sep 2013 14:56:13 -0500 Subject: [PATCH 29/36] Bug 898055 - Enable apz in metrofx. r=jimm --- browser/metro/profile/metro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/metro/profile/metro.js b/browser/metro/profile/metro.js index 5949bf3a8670..3253f9528874 100644 --- a/browser/metro/profile/metro.js +++ b/browser/metro/profile/metro.js @@ -34,7 +34,7 @@ pref("prompts.tab_modal.enabled", true); // Enable off main thread compositing pref("layers.offmainthreadcomposition.enabled", true); -pref("layers.async-pan-zoom.enabled", false); +pref("layers.async-pan-zoom.enabled", true); pref("layers.componentalpha.enabled", false); pref("gfx.azpc.touch_start_tolerance", "0.1"); // dpi * tolerance = pixel threshold pref("gfx.axis.fling_friction", "0.002"); From 77e3ab9b5b69c44cc31816193fe707a8ffb38060 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 6 Sep 2013 14:56:13 -0500 Subject: [PATCH 30/36] Bug 898055 - Disable some apz debug output. r=bbondy --- browser/metro/base/content/apzc.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/browser/metro/base/content/apzc.js b/browser/metro/base/content/apzc.js index 0509c2950ce3..444edc263005 100644 --- a/browser/metro/base/content/apzc.js +++ b/browser/metro/base/content/apzc.js @@ -15,6 +15,7 @@ let Cr = Components.results; */ var APZCObserver = { + _debugEvents: false, init: function() { this._enabled = Services.prefs.getBoolPref(kAsyncPanZoomEnabled); if (!this._enabled) { @@ -95,25 +96,23 @@ var APZCObserver = { id: scrollId }); - Util.dumpLn("APZC scrollId: " + scrollId); - Util.dumpLn("APZC scrollTo.x: " + scrollTo.x + ", scrollTo.y: " + scrollTo.y); - Util.dumpLn("APZC setResolution: " + resolution); - Util.dumpLn("APZC setDisplayPortForElement: displayPort.x: " + - displayPort.x + ", displayPort.y: " + displayPort.y + - ", displayPort.width: " + displayPort.width + - ", displayort.height: " + displayPort.height); + if (this._debugEvents) { + Util.dumpLn("APZC scrollId: " + scrollId); + Util.dumpLn("APZC scrollTo.x: " + scrollTo.x + ", scrollTo.y: " + scrollTo.y); + Util.dumpLn("APZC setResolution: " + resolution); + Util.dumpLn("APZC setDisplayPortForElement: displayPort.x: " + + displayPort.x + ", displayPort.y: " + displayPort.y + + ", displayPort.width: " + displayPort.width + + ", displayort.height: " + displayPort.height); + } } else if (aTopic == "apzc-handle-pan-begin") { // When we're panning, hide the main scrollbars by setting imprecise // input (which sets a property on the browser which hides the scrollbar // via CSS). This reduces jittering from left to right. We may be able // to get rid of this once we implement axis locking in /gfx APZC. - Util.dumpLn("APZC pan-begin"); if (InputSourceHelper.isPrecise) { InputSourceHelper._imprecise(); } - - } else if (aTopic == "apzc-handle-pan-end") { - Util.dumpLn("APZC pan-end"); } }, From 1585b0c5ba9abb25fefc032f38acad465a16bef7 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 6 Sep 2013 14:56:13 -0500 Subject: [PATCH 31/36] Bug 912931 - Fix for double click events with apz enabled. r=bbondy --- widget/windows/winrt/MetroWidget.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index 28b330a3bc53..f7e81595ef82 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -1532,37 +1532,16 @@ MetroWidget::RequestContentRepaint(const FrameMetrics& aFrameMetrics) void MetroWidget::HandleDoubleTap(const CSSIntPoint& aPoint) { - LogFunction(); - - if (!mMetroInput) { - return; - } - - mMetroInput->HandleDoubleTap(CSSIntPointToLayoutDeviceIntPoint(aPoint)); } void MetroWidget::HandleSingleTap(const CSSIntPoint& aPoint) { - LogFunction(); - - if (!mMetroInput) { - return; - } - - mMetroInput->HandleSingleTap(CSSIntPointToLayoutDeviceIntPoint(aPoint)); } void MetroWidget::HandleLongTap(const CSSIntPoint& aPoint) { - LogFunction(); - - if (!mMetroInput) { - return; - } - - mMetroInput->HandleLongTap(CSSIntPointToLayoutDeviceIntPoint(aPoint)); } void From ffa1f7547967d1c967f9fe7f25cb5e29a5ecba61 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Fri, 6 Sep 2013 14:56:14 -0500 Subject: [PATCH 32/36] Bug 913114 - Fix ref counting in winrt widget's GeckoContentController. r=bbondy --- widget/windows/winrt/APZController.cpp | 107 +++++++++++++++++++++++++ widget/windows/winrt/APZController.h | 32 ++++++++ widget/windows/winrt/FrameworkView.cpp | 1 - widget/windows/winrt/FrameworkView.h | 2 +- widget/windows/winrt/MetroApp.cpp | 1 + widget/windows/winrt/MetroInput.cpp | 24 +----- widget/windows/winrt/MetroInput.h | 2 - widget/windows/winrt/MetroWidget.cpp | 100 +---------------------- widget/windows/winrt/MetroWidget.h | 45 ++++------- widget/windows/winrt/moz.build | 1 + 10 files changed, 159 insertions(+), 156 deletions(-) create mode 100644 widget/windows/winrt/APZController.cpp create mode 100644 widget/windows/winrt/APZController.h diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp new file mode 100644 index 000000000000..a9bad89671ab --- /dev/null +++ b/widget/windows/winrt/APZController.cpp @@ -0,0 +1,107 @@ +/* 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 "APZController.h" +#include "base/message_loop.h" +#include "mozilla/layers/GeckoContentController.h" +#include "nsThreadUtils.h" +#include "MetroUtils.h" +#include "nsPrintfCString.h" + +namespace mozilla { +namespace widget { +namespace winrt { + +class RequestContentRepaintEvent : public nsRunnable +{ + typedef mozilla::layers::FrameMetrics FrameMetrics; + +public: + RequestContentRepaintEvent(const FrameMetrics& aFrameMetrics) : mFrameMetrics(aFrameMetrics) + { + } + + NS_IMETHOD Run() { + // This event shuts down the worker thread and so must be main thread. + MOZ_ASSERT(NS_IsMainThread()); + + CSSToScreenScale resolution = mFrameMetrics.mZoom; + CSSRect compositedRect = mFrameMetrics.CalculateCompositedRectInCssPixels(); + + NS_ConvertASCIItoUTF16 data(nsPrintfCString("{ " \ + " \"resolution\": %.2f, " \ + " \"scrollId\": %d, " \ + " \"compositedRect\": { \"width\": %d, \"height\": %d }, " \ + " \"displayPort\": { \"x\": %d, \"y\": %d, \"width\": %d, \"height\": %d }, " \ + " \"scrollTo\": { \"x\": %d, \"y\": %d }" \ + "}", + (float)(resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel.scale), + (int)mFrameMetrics.mScrollId, + (int)compositedRect.width, + (int)compositedRect.height, + (int)mFrameMetrics.mDisplayPort.x, + (int)mFrameMetrics.mDisplayPort.y, + (int)mFrameMetrics.mDisplayPort.width, + (int)mFrameMetrics.mDisplayPort.height, + (int)mFrameMetrics.mScrollOffset.x, + (int)mFrameMetrics.mScrollOffset.y)); + + MetroUtils::FireObserver("apzc-request-content-repaint", data.get()); + return NS_OK; + } +protected: + const FrameMetrics mFrameMetrics; +}; + +void +APZController::RequestContentRepaint(const FrameMetrics& aFrameMetrics) +{ + // Send the result back to the main thread so that it can shutdown + nsCOMPtr r1 = new RequestContentRepaintEvent(aFrameMetrics); + if (!NS_IsMainThread()) { + NS_DispatchToMainThread(r1); + } else { + r1->Run(); + } +} + +void +APZController::HandleDoubleTap(const CSSIntPoint& aPoint) +{ +} + +void +APZController::HandleSingleTap(const CSSIntPoint& aPoint) +{ +} + +void +APZController::HandleLongTap(const CSSIntPoint& aPoint) +{ +} + +void +APZController::SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const CSSRect &aContentRect, const CSSSize &aScrollableSize) +{ +} + +void +APZController::PostDelayedTask(Task* aTask, int aDelayMs) +{ + MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs); +} + +void +APZController::HandlePanBegin() +{ + MetroUtils::FireObserver("apzc-handle-pan-begin", L""); +} + +void +APZController::HandlePanEnd() +{ + MetroUtils::FireObserver("apzc-handle-pan-end", L""); +} + +} } } \ No newline at end of file diff --git a/widget/windows/winrt/APZController.h b/widget/windows/winrt/APZController.h new file mode 100644 index 000000000000..8542b2fd94f1 --- /dev/null +++ b/widget/windows/winrt/APZController.h @@ -0,0 +1,32 @@ +/* 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/. */ + +#pragma once + +#include "mozwrlbase.h" + +#include "mozilla/layers/GeckoContentController.h" +#include "FrameMetrics.h" +#include "Units.h" + +namespace mozilla { +namespace widget { +namespace winrt { + +class APZController : public mozilla::layers::GeckoContentController +{ + typedef mozilla::layers::FrameMetrics FrameMetrics; + +public: + virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics); + virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint); + virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint); + virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint); + virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize); + virtual void PostDelayedTask(Task* aTask, int aDelayMs); + virtual void HandlePanBegin(); + virtual void HandlePanEnd(); +}; + +} } } \ No newline at end of file diff --git a/widget/windows/winrt/FrameworkView.cpp b/widget/windows/winrt/FrameworkView.cpp index 76e3638f5bbf..49de0d97df09 100644 --- a/widget/windows/winrt/FrameworkView.cpp +++ b/widget/windows/winrt/FrameworkView.cpp @@ -197,7 +197,6 @@ FrameworkView::ShutdownXPCOM() mAutomationProvider = nullptr; mMetroInput = nullptr; - mD2DWindowSurface = nullptr; delete sSettingsArray; sSettingsArray = nullptr; mWidget = nullptr; diff --git a/widget/windows/winrt/FrameworkView.h b/widget/windows/winrt/FrameworkView.h index b3f56cf6f082..f1fcb1e745d7 100644 --- a/widget/windows/winrt/FrameworkView.h +++ b/widget/windows/winrt/FrameworkView.h @@ -7,6 +7,7 @@ #include "nsGUIEvent.h" #include "MetroWidget.h" +#include "MetroInput.h" #include "gfxWindowsPlatform.h" #include "gfxD2DSurface.h" #include "nsDataHashtable.h" @@ -176,7 +177,6 @@ private: EventRegistrationToken mPrintManager; private: - nsRefPtr mD2DWindowSurface; nsIntRect mWindowBounds; // in device-pixel coordinates float mDPI; bool mShuttingDown; diff --git a/widget/windows/winrt/MetroApp.cpp b/widget/windows/winrt/MetroApp.cpp index 776e72e70459..7d9dbefb3ecc 100644 --- a/widget/windows/winrt/MetroApp.cpp +++ b/widget/windows/winrt/MetroApp.cpp @@ -107,6 +107,7 @@ MetroApp::ShutdownXPCOM() void MetroApp::CoreExit() { + LogFunction(); HRESULT hr; ComPtr coreExit; HStringReference className(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication); diff --git a/widget/windows/winrt/MetroInput.cpp b/widget/windows/winrt/MetroInput.cpp index 69a3fb7bf876..d57192b543e0 100644 --- a/widget/windows/winrt/MetroInput.cpp +++ b/widget/windows/winrt/MetroInput.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Moz headers (alphabetical) +#include "MetroInput.h" #include "MetroUtils.h" // Logging, POINT_CEIL_*, ActivateGenericInstance, etc #include "MetroWidget.h" // MetroInput::mWidget #include "mozilla/dom/Touch.h" // Touch @@ -161,8 +162,6 @@ MetroInput::MetroInput(MetroWidget* aWidget, NS_ASSERTION(aWidget, "Attempted to create MetroInput for null widget!"); NS_ASSERTION(aWindow, "Attempted to create MetroInput for null window!"); - mWidget->SetMetroInput(this); - mTokenPointerPressed.value = 0; mTokenPointerReleased.value = 0; mTokenPointerMoved.value = 0; @@ -928,27 +927,6 @@ MetroInput::OnRightTapped(UI::Input::IGestureRecognizer* aSender, return S_OK; } -// Used by MetroWidget GeckoContentController callbacks -void -MetroInput::HandleDoubleTap(const LayoutDeviceIntPoint& aPoint) -{ -#ifdef DEBUG_INPUT - LogFunction(); -#endif - nsSimpleGestureEvent* tapEvent = - new nsSimpleGestureEvent(true, - NS_SIMPLE_GESTURE_TAP, - mWidget.Get(), - 0, - 0.0); - - tapEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; - tapEvent->refPoint = aPoint; - tapEvent->clickCount = 2; - tapEvent->pressure = 1; - DispatchAsyncEventIgnoreStatus(tapEvent); -} - void MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint) { diff --git a/widget/windows/winrt/MetroInput.h b/widget/windows/winrt/MetroInput.h index 826fc64e679e..cc9223ef4f8d 100644 --- a/widget/windows/winrt/MetroInput.h +++ b/widget/windows/winrt/MetroInput.h @@ -147,8 +147,6 @@ public: HRESULT OnRightTapped(IGestureRecognizer* aSender, IRightTappedEventArgs* aArgs); - // Used by MetroWidget GeckoContentController callbacks - void HandleDoubleTap(const mozilla::LayoutDeviceIntPoint& aPoint); void HandleSingleTap(const mozilla::LayoutDeviceIntPoint& aPoint); void HandleLongTap(const mozilla::LayoutDeviceIntPoint& aPoint); diff --git a/widget/windows/winrt/MetroWidget.cpp b/widget/windows/winrt/MetroWidget.cpp index f7e81595ef82..f260eee4cf87 100644 --- a/widget/windows/winrt/MetroWidget.cpp +++ b/widget/windows/winrt/MetroWidget.cpp @@ -962,7 +962,8 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa if (ShouldUseAPZC()) { mRootLayerTreeId = compositor->RootLayerTreeId(); - CompositorParent::SetControllerForLayerTree(mRootLayerTreeId, this); + mController = new APZController(); + CompositorParent::SetControllerForLayerTree(mRootLayerTreeId, mController); MetroWidget::sAPZC = CompositorParent::GetAPZCTreeManager(compositor->RootLayerTreeId()); MetroWidget::sAPZC->SetDPI(GetDPI()); @@ -1474,103 +1475,6 @@ MetroWidget::HasPendingInputEvent() return false; } -// GeckoContentController interface impl - -class RequestContentRepaintEvent : public nsRunnable -{ -public: - RequestContentRepaintEvent(const FrameMetrics& aFrameMetrics) : mFrameMetrics(aFrameMetrics) - { - } - - NS_IMETHOD Run() { - // This event shuts down the worker thread and so must be main thread. - MOZ_ASSERT(NS_IsMainThread()); - - CSSToScreenScale resolution = mFrameMetrics.mZoom; - CSSRect compositedRect = mFrameMetrics.CalculateCompositedRectInCssPixels(); - - NS_ConvertASCIItoUTF16 data(nsPrintfCString("{ " \ - " \"resolution\": %.2f, " \ - " \"scrollId\": %d, " \ - " \"compositedRect\": { \"width\": %d, \"height\": %d }, " \ - " \"displayPort\": { \"x\": %d, \"y\": %d, \"width\": %d, \"height\": %d }, " \ - " \"scrollTo\": { \"x\": %d, \"y\": %d }" \ - "}", - (float)(resolution.scale / mFrameMetrics.mDevPixelsPerCSSPixel.scale), - (int)mFrameMetrics.mScrollId, - (int)compositedRect.width, - (int)compositedRect.height, - (int)mFrameMetrics.mDisplayPort.x, - (int)mFrameMetrics.mDisplayPort.y, - (int)mFrameMetrics.mDisplayPort.width, - (int)mFrameMetrics.mDisplayPort.height, - (int)mFrameMetrics.mScrollOffset.x, - (int)mFrameMetrics.mScrollOffset.y)); - - MetroUtils::FireObserver("apzc-request-content-repaint", data.get()); - return NS_OK; - } -protected: - const FrameMetrics mFrameMetrics; -}; - -void -MetroWidget::RequestContentRepaint(const FrameMetrics& aFrameMetrics) -{ - LogFunction(); - - // Send the result back to the main thread so that it can shutdown - nsCOMPtr r1 = new RequestContentRepaintEvent(aFrameMetrics); - if (!NS_IsMainThread()) { - NS_DispatchToMainThread(r1); - } else { - r1->Run(); - } -} - -void -MetroWidget::HandleDoubleTap(const CSSIntPoint& aPoint) -{ -} - -void -MetroWidget::HandleSingleTap(const CSSIntPoint& aPoint) -{ -} - -void -MetroWidget::HandleLongTap(const CSSIntPoint& aPoint) -{ -} - -void -MetroWidget::SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const CSSRect &aContentRect, const CSSSize &aScrollableSize) -{ - LogFunction(); -} - -void -MetroWidget::PostDelayedTask(Task* aTask, int aDelayMs) -{ - LogFunction(); - MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs); -} - -void -MetroWidget::HandlePanBegin() -{ - LogFunction(); - MetroUtils::FireObserver("apzc-handle-pan-begin", L""); -} - -void -MetroWidget::HandlePanEnd() -{ - LogFunction(); - MetroUtils::FireObserver("apzc-handle-pan-end", L""); -} - NS_IMETHODIMP MetroWidget::Observe(nsISupports *subject, const char *topic, const PRUnichar *data) { diff --git a/widget/windows/winrt/MetroWidget.h b/widget/windows/winrt/MetroWidget.h index c83b99b46128..b958a210fcde 100644 --- a/widget/windows/winrt/MetroWidget.h +++ b/widget/windows/winrt/MetroWidget.h @@ -22,11 +22,11 @@ #include "mozilla/a11y/Accessible.h" #endif #include "mozilla/layers/CompositorParent.h" -#include "mozilla/layers/GeckoContentController.h" #include "mozilla/layers/APZCTreeManager.h" #include "mozilla/layers/LayerManagerComposite.h" #include "Units.h" -#include "MetroInput.h" +#include "nsDeque.h" +#include "APZController.h" #include "mozwrlbase.h" @@ -48,7 +48,6 @@ class FrameworkView; class DispatchMsg; class MetroWidget : public nsWindowBase, - public mozilla::layers::GeckoContentController, public nsIObserver { typedef mozilla::widget::WindowHook WindowHook; @@ -58,7 +57,7 @@ class MetroWidget : public nsWindowBase, typedef ABI::Windows::UI::Core::IKeyEventArgs IKeyEventArgs; typedef ABI::Windows::UI::Core::ICharacterReceivedEventArgs ICharacterReceivedEventArgs; typedef mozilla::widget::winrt::FrameworkView FrameworkView; - typedef mozilla::layers::FrameMetrics FrameMetrics; + typedef mozilla::widget::winrt::APZController APZController; static LRESULT CALLBACK StaticWindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParan, LPARAM aLParam); @@ -200,21 +199,6 @@ public: nsresult RequestContentScroll(); void RequestContentRepaintImplMainThread(); - // GeckoContentController interface impl - virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics); - virtual void HandleDoubleTap(const mozilla::CSSIntPoint& aPoint); - virtual void HandleSingleTap(const mozilla::CSSIntPoint& aPoint); - virtual void HandleLongTap(const mozilla::CSSIntPoint& aPoint); - virtual void SendAsyncScrollDOMEvent(FrameMetrics::ViewID aScrollId, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize); - virtual void PostDelayedTask(Task* aTask, int aDelayMs); - virtual void HandlePanBegin(); - virtual void HandlePanEnd(); - - void SetMetroInput(mozilla::widget::winrt::MetroInput* aMetroInput) - { - mMetroInput = aMetroInput; - } - protected: friend class FrameworkView; @@ -238,6 +222,16 @@ protected: void RemoveSubclass(); nsIWidgetListener* GetPaintListener(); + // Async event dispatching + void DispatchAsyncScrollEvent(DispatchMsg* aEvent); + void DeliverNextScrollEvent(); + void DeliverNextKeyboardEvent(); + DispatchMsg* CreateDispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam); + +public: + static nsRefPtr sAPZC; + +protected: OleInitializeWrapper mOleInitializeWrapper; WindowHook mWindowHook; Microsoft::WRL::ComPtr mView; @@ -248,19 +242,8 @@ protected: static HWND sICoreHwnd; WNDPROC mMetroWndProc; bool mTempBasicLayerInUse; - Microsoft::WRL::ComPtr mMetroInput; - mozilla::layers::FrameMetrics mFrameMetrics; uint64_t mRootLayerTreeId; - - // Async event dispatching - void DispatchAsyncScrollEvent(DispatchMsg* aEvent); - void DeliverNextScrollEvent(); - void DeliverNextKeyboardEvent(); - DispatchMsg* CreateDispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam); - nsDeque mMsgEventQueue; nsDeque mKeyEventQueue; - -public: - static nsRefPtr sAPZC; + nsRefPtr mController; }; diff --git a/widget/windows/winrt/moz.build b/widget/windows/winrt/moz.build index e899b282fadf..0f379880d6c0 100644 --- a/widget/windows/winrt/moz.build +++ b/widget/windows/winrt/moz.build @@ -19,6 +19,7 @@ CPP_SOURCES += [ 'UIABridge.cpp', 'nsMetroFilePicker.cpp', 'nsWinMetroUtils.cpp', + 'APZController.cpp', ] EXTRA_COMPONENTS += [ From 08aa1fb872144436f85df3e85c25ade51d565e7a Mon Sep 17 00:00:00 2001 From: Wes Johnston Date: Fri, 6 Sep 2013 15:29:04 -0700 Subject: [PATCH 33/36] Bug 878418 - Move positioning of Open with context menu item. r=mfinkle --- mobile/android/chrome/content/browser.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 7eaab9052b54..83f05ec2dc6d 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -334,7 +334,6 @@ var BrowserApp = { Reader.init(); UserAgentOverrides.init(); DesktopUserAgent.init(); - ExternalApps.init(); Distribution.init(); Tabs.init(); #ifdef ACCESSIBILITY @@ -368,6 +367,9 @@ var BrowserApp = { SearchEngines.init(); this.initContextMenu(); } + // The order that context menu items are added is important + // Make sure the "Open in App" context menu item appears at the bottom of the list + ExternalApps.init(); // XXX maybe we don't do this if the launch was kicked off from external Services.io.offline = false; From 53d70734e26bdecbdbfbed64bde6565bded33dec Mon Sep 17 00:00:00 2001 From: Margaret Leibovic Date: Fri, 6 Sep 2013 16:25:27 -0700 Subject: [PATCH 34/36] Bug 909455 - Replace FHR recordSearch calls in new URL entering logic. r=rnewman --- mobile/android/base/BrowserApp.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/mobile/android/base/BrowserApp.java b/mobile/android/base/BrowserApp.java index a44c76fc76ae..86ad24403a8c 100644 --- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -13,6 +13,7 @@ import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.ImmutableViewportMetrics; import org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.gfx.PanZoomController; +import org.mozilla.gecko.health.BrowserHealthRecorder; import org.mozilla.gecko.health.BrowserHealthReporter; import org.mozilla.gecko.home.BrowserSearch; import org.mozilla.gecko.home.HomePager; @@ -1464,6 +1465,8 @@ abstract public class BrowserApp extends GeckoApp return; } + recordSearch(null, "barkeyword"); + // Otherwise, construct a search query from the bookmark keyword. final String searchUrl = keywordUrl.replace("%s", URLEncoder.encode(keywordSearch)); Tabs.getInstance().loadUrl(searchUrl, Tabs.LOADURL_USER_ENTERED); @@ -1471,6 +1474,28 @@ abstract public class BrowserApp extends GeckoApp }); } + /** + * Record in Health Report that a search has occurred. + * + * @param identifier + * a search identifier, such as "partnername". Can be null. + * @param where + * where the search was initialized; one of the values in + * {@link BrowserHealthRecorder#SEARCH_LOCATIONS}. + */ + private static void recordSearch(String identifier, String where) { + Log.i(LOGTAG, "Recording search: " + identifier + ", " + where); + try { + JSONObject message = new JSONObject(); + message.put("type", BrowserHealthRecorder.EVENT_SEARCH); + message.put("location", where); + message.put("identifier", identifier); + GeckoAppShell.getEventDispatcher().dispatchEvent(message); + } catch (Exception e) { + Log.w(LOGTAG, "Error recording search.", e); + } + } + boolean dismissEditingMode() { if (!mBrowserToolbar.isEditing()) { return false; @@ -2209,6 +2234,7 @@ abstract public class BrowserApp extends GeckoApp // BrowserSearch.OnSearchListener @Override public void onSearch(String engineId, String text) { + recordSearch(engineId, "barsuggest"); openUrl(text, engineId); } From fe358a0040002cacee5ab4cfd396b6df4b7b9a05 Mon Sep 17 00:00:00 2001 From: Margaret Leibovic Date: Fri, 6 Sep 2013 16:25:37 -0700 Subject: [PATCH 35/36] Bug 907192 - Update tab count while in editing mode on tablets. r=lucasr --- mobile/android/base/BrowserToolbar.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mobile/android/base/BrowserToolbar.java b/mobile/android/base/BrowserToolbar.java index 857963869175..1f1cf828c663 100644 --- a/mobile/android/base/BrowserToolbar.java +++ b/mobile/android/base/BrowserToolbar.java @@ -861,11 +861,11 @@ public class BrowserToolbar extends GeckoRelativeLayout return; } - // If toolbar is in edit mode, this means the entry is expanded and the - // tabs button is translated offscreen. Don't trigger tabs counter + // If toolbar is in edit mode on a phone, this means the entry is expanded + // and the tabs button is translated offscreen. Don't trigger tabs counter // updates until the tabs button is back on screen. // See stopEditing() - if (!isEditing()) { + if (!isEditing() || HardwareUtils.isTablet()) { mTabsCounter.setCount(count); mTabs.setContentDescription((count > 1) ? @@ -875,11 +875,11 @@ public class BrowserToolbar extends GeckoRelativeLayout } public void updateTabCount(int count) { - // If toolbar is in edit mode, this means the entry is expanded and the - // tabs button is translated offscreen. Don't trigger tabs counter + // If toolbar is in edit mode on a phone, this means the entry is expanded + // and the tabs button is translated offscreen. Don't trigger tabs counter // updates until the tabs button is back on screen. // See stopEditing() - if (isEditing()) { + if (isEditing() && !HardwareUtils.isTablet()) { return; } @@ -1378,9 +1378,10 @@ public class BrowserToolbar extends GeckoRelativeLayout if (HardwareUtils.isTablet() || Build.VERSION.SDK_INT < 11) { hideUrlEditContainer(); - updateTabCountAndAnimate(Tabs.getInstance().getDisplayCount()); if (!HardwareUtils.isTablet()) { + updateTabCountAndAnimate(Tabs.getInstance().getDisplayCount()); + if (mUrlBarRightEdge != null) { ViewHelper.setTranslationX(mUrlBarRightEdge, 0); } From d52864cae35ba4942c74673cc7d5a1efb99285d0 Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Fri, 6 Sep 2013 17:38:03 -0700 Subject: [PATCH 36/36] Backout 2255560d9b6c (bug 912054) for breaking PGO builds on the UX branch (bug 913251) --- gfx/src/nsRegion.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gfx/src/nsRegion.cpp b/gfx/src/nsRegion.cpp index cbf937be726d..c984de9e9088 100644 --- a/gfx/src/nsRegion.cpp +++ b/gfx/src/nsRegion.cpp @@ -246,9 +246,7 @@ void nsRegion::Init() mRectListHead.prev = mRectListHead.next = &mRectListHead; mCurRect = &mRectListHead; mRectCount = 0; - MOZ_ASSERT(mBoundRect.x == 0 && mBoundRect.y == 0 && - mBoundRect.width == 0 && mBoundRect.height == 0, - "Caller must have initialized mBoundRect"); + mBoundRect.SetRect (0, 0, 0, 0); } inline void nsRegion::InsertBefore (RgnRect* aNewRect, RgnRect* aRelativeRect)