author | Ryan VanderMeulen <ryanvm@gmail.com> |
Thu, 15 Nov 2012 20:21:35 -0500 | |
changeset 113409 | 58ebb638a7ea6c3a4a19fa45c0bd8b9818c12542 |
parent 113378 | a37525d304d933d39836a1639b73da440a715602 (current diff) |
parent 113408 | bbf5d4a4e73e4a7e136f0a9a8c7fbcf88d0cd1af (diff) |
child 113410 | a50a77da3cf90fa73b3cf00ad78ba18de36f3e89 |
child 113447 | b7c7be527638eb90e30e46f757582cb77924afbc |
child 117344 | 0b9c66c707ae2442b61e13fbec8c605fd3090c9f |
push id | 23870 |
push user | ryanvm@gmail.com |
push date | Fri, 16 Nov 2012 01:21:36 +0000 |
treeherder | mozilla-central@58ebb638a7ea [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 19.0a1 |
first release with | nightly linux32
58ebb638a7ea
/
19.0a1
/
20121116030725
/
files
nightly linux64
58ebb638a7ea
/
19.0a1
/
20121116030725
/
files
nightly mac
58ebb638a7ea
/
19.0a1
/
20121116030725
/
files
nightly win32
58ebb638a7ea
/
19.0a1
/
20121116030725
/
files
nightly win64
58ebb638a7ea
/
19.0a1
/
20121116030725
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
19.0a1
/
20121116030725
/
pushlog to previous
nightly linux64
19.0a1
/
20121116030725
/
pushlog to previous
nightly mac
19.0a1
/
20121116030725
/
pushlog to previous
nightly win32
19.0a1
/
20121116030725
/
pushlog to previous
nightly win64
19.0a1
/
20121116030725
/
pushlog to previous
|
--- a/accessible/build/Makefile.in +++ b/accessible/build/Makefile.in @@ -24,17 +24,16 @@ CPPSRCS = nsAccessibilityFactory.cpp LOCAL_INCLUDES = -I$(srcdir)/../src SHARED_LIBRARY_LIBS = \ ../src/base/$(LIB_PREFIX)accessibility_base_s.$(LIB_SUFFIX) \ ../src/generic/$(LIB_PREFIX)accessibility_generic_s.$(LIB_SUFFIX) \ ../src/html/$(LIB_PREFIX)accessibility_html_s.$(LIB_SUFFIX) \ ../src/xpcom/$(LIB_PREFIX)accessibility_xpcom_s.$(LIB_SUFFIX) \ ../src/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) \ - ../src/xforms/$(LIB_PREFIX)accessibility_xforms_s.$(LIB_SUFFIX) \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),windows) SHARED_LIBRARY_LIBS += \ ../src/windows/ia2/$(LIB_PREFIX)accessibility_toolkit_ia2_s.$(LIB_SUFFIX) \ ../src/windows/uia/$(LIB_PREFIX)accessibility_toolkit_uia_s.$(LIB_SUFFIX) \ $(NULL) endif
--- a/accessible/public/nsIAccessibleProvider.idl +++ b/accessible/public/nsIAccessibleProvider.idl @@ -6,17 +6,17 @@ #include "nsISupports.idl" /** * nsIAccessibleProvider interface is used to link element and accessible object. For that XBL binding of element should implement the interface. */ -[scriptable, uuid(ac0639d5-f95b-4e2b-970c-9eab281fb6a5)] +[scriptable, uuid(f7e531b6-bc29-4d3d-8c91-60fc2b71eb40)] interface nsIAccessibleProvider : nsISupports { /** * Constants set of common use. */ /** Do not create an accessible for this object * This is useful if an ancestor binding already implements nsIAccessibleProvider, @@ -71,68 +71,13 @@ interface nsIAccessibleProvider : nsISup const long XULTree = 0x0000101D; const long XULTreeColumns = 0x0000101E; const long XULTreeColumnItem = 0x0000101F; const long XULToolbar = 0x00001020; const long XULToolbarSeparator = 0x00001021; const long XULTooltip = 0x00001022; const long XULToolbarButton = 0x00001023; - - /** - * Constants set is used by XForms elements. - */ - - /** Used for xforms elements that provide accessible object for itself as - * well for anonymous content. This property are used for upload, - * input[type="xsd:gDay"] and input[type="xsd:gMonth"] */ - const long XFormsContainer = 0x00002000; - - /** Used for label element */ - const long XFormsLabel = 0x00002001; - /** Used for output element */ - const long XFormsOutput = 0x00002002; - /** Used for trigger and submit elements */ - const long XFormsTrigger = 0x00002003; - /** Used for input and textarea elements */ - const long XFormsInput = 0x00002004; - /** Used for input[xsd:boolean] element */ - const long XFormsInputBoolean = 0x00002005; - /** Used for input[xsd:date] element */ - const long XFormsInputDate = 0x00002006; - /** Used for secret element */ - const long XFormsSecret = 0x00002007; - /** Used for range element represented by slider */ - const long XFormsSliderRange = 0x00002008; - - /** Used for select and select1 that are implemented using host document's - * native widget. For example, a select1 in a xhtml document may be - * represented by the native html control html:select */ - const long XFormsSelect = 0x00002009; - /** Used for xforms choices element */ - const long XFormsChoices = 0x00002010; - /** Used for xforms full select/select1 elements that may be represented by - * group of checkboxes and radiogroup */ - const long XFormsSelectFull = 0x00002011; - /** Used for xforms item element that is used inside xforms select elements - * represented by group of checkboxes */ - const long XFormsItemCheckgroup = 0x00002012; - /** Used for xforms item element that is used inside xforms select1 elements - * represented by radio group */ - const long XFormsItemRadiogroup = 0x00002013; - /** Used for xforms select1 element that is represented by combobox */ - const long XFormsSelectCombobox = 0x00002014; - /** Used for xforms item element that is used inside xforms select1 - * elements represented by combobox */ - const long XFormsItemCombobox = 0x00002015; - - /** Used for dropmarker widget that is used by xforms elements */ - const long XFormsDropmarkerWidget = 0x00002101; - /** Used for calendar widget that is used by xforms elements */ - const long XFormsCalendarWidget = 0x00002102; - /** Used for popup widget that is used by xforms minimal select1 elements */ - const long XFormsComboboxPopupWidget = 0x00002103; - /** * Return one of constants declared above. */ readonly attribute long accessibleType; };
--- a/accessible/public/nsIAccessibleRole.idl +++ b/accessible/public/nsIAccessibleRole.idl @@ -57,17 +57,17 @@ interface nsIAccessibleRole : nsISupport */ const unsigned long ROLE_CARET = 7; /** * Represents an alert or a condition that a user should be notified about. * Assistive Technologies typically respond to the role by reading the entire * onscreen contents of containers advertising this role. Should be used for * warning dialogs, etc. The role is used by xul:browsermessage, - * role="alert", xforms:message. + * role="alert". */ const unsigned long ROLE_ALERT = 8; /** * Represents the window frame, which contains child objects such as * a title bar, client, and other objects contained in a window. The role * is supported automatically by MS Windows. */ @@ -197,18 +197,17 @@ interface nsIAccessibleRole : nsISupport * Represents a cell within a table. It is used for html:td, * xul:tree cell and xul:listcell. Also, see ROLE_TABLE. */ const unsigned long ROLE_CELL = 29; /** * Represents a link to something else. This object might look like text or * a graphic, but it acts like a button. It is used for - * xul:label@class="text-link", html:a, html:area, - * xforms:trigger@appearance="minimal". + * xul:label@class="text-link", html:a, html:area. */ const unsigned long ROLE_LINK = 30; /** * Displays a Help topic in the form of a ToolTip or Help balloon. */ const unsigned long ROLE_HELPBALLOON = 31; @@ -264,35 +263,34 @@ interface nsIAccessibleRole : nsISupport /** * Represents a picture. Is is used for xul:image, html:img. */ const unsigned long ROLE_GRAPHIC = 40; /** * Represents read-only text, such as labels for other controls or * instructions in a dialog box. Static text cannot be modified or selected. - * Is is used for xul:label, xul:description, html:label, role="label", - * or xforms:output. + * Is is used for xul:label, xul:description, html:label, role="label". */ const unsigned long ROLE_STATICTEXT = 41; /** * Represents selectable text that allows edits or is designated read-only. */ const unsigned long ROLE_TEXT_LEAF = 42; /** * Represents a push button control. It is used for xul:button, html:button, - * role="button", xforms:trigger, xforms:submit. + * role="button". */ const unsigned long ROLE_PUSHBUTTON = 43; /** * Represents a check box control. It is used for xul:checkbox, - * html:input@type="checkbox", role="checkbox", boolean xforms:input. + * html:input@type="checkbox", role="checkbox". */ const unsigned long ROLE_CHECKBUTTON = 44; /** * Represents an option button, also called a radio button. It is one of a * group of mutually exclusive options. All objects sharing a single parent * that have this attribute are assumed to be part of single mutually * exclusive group. It is used for xul:radio, html:input@type="radio", @@ -303,17 +301,17 @@ interface nsIAccessibleRole : nsISupport /** * Represents a combo box; an edit control with an associated list box that * provides a set of predefined choices. It is used for html:select, * xul:menulist, role="combobox". */ const unsigned long ROLE_COMBOBOX = 46; /** - * Represents the calendar control. It is used for date xforms:input. + * Represents the calendar control. */ const unsigned long ROLE_DROPLIST = 47; /** * Represents a progress bar, dynamically showing the user the percent * complete of an operation in progress. It is used for xul:progressmeter, * role="progressbar". */ @@ -328,17 +326,17 @@ interface nsIAccessibleRole : nsISupport * Represents a hot-key field that allows the user to enter a combination or * sequence of keystrokes. */ const unsigned long ROLE_HOTKEYFIELD = 50; /** * Represents a slider, which allows the user to adjust a setting in given * increments between minimum and maximum values. It is used by xul:scale, - * role="slider", xforms:range. + * role="slider". */ const unsigned long ROLE_SLIDER = 51; /** * Represents a spin box, which is a control that allows the user to increment * or decrement the value displayed in a separate "buddy" control associated * with the spin box. It is used for xul:spinbuttons. */
--- a/accessible/src/Makefile.in +++ b/accessible/src/Makefile.in @@ -39,16 +39,15 @@ endif DIRS += $(PLATFORM_DIR) DIRS += \ base \ generic \ html \ jsat \ xpcom \ - xforms \ $(null) ifdef MOZ_XUL DIRS += xul endif include $(topsrcdir)/config/rules.mk
--- a/accessible/src/base/Makefile.in +++ b/accessible/src/base/Makefile.in @@ -74,17 +74,16 @@ FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk LOCAL_INCLUDES += \ -I$(srcdir) \ -I$(srcdir)/../generic \ -I$(srcdir)/../html \ -I$(srcdir)/../xpcom \ -I$(srcdir)/../xul \ - -I$(srcdir)/../xforms \ -I$(srcdir)/../../../layout/generic \ -I$(srcdir)/../../../layout/style \ -I$(srcdir)/../../../layout/xul/base/src \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) LOCAL_INCLUDES += \ -I$(srcdir)/../atk \
--- a/accessible/src/base/Role.h +++ b/accessible/src/base/Role.h @@ -64,17 +64,17 @@ enum Role { */ CARET = 7, /** * Represents an alert or a condition that a user should be notified about. * Assistive Technologies typically respond to the role by reading the entire * onscreen contents of containers advertising this role. Should be used for * warning dialogs, etc. The role is used by xul:browsermessage, - * role="alert", xforms:message. + * role="alert". */ ALERT = 8, /** * Represents the window frame, which contains child objects such as * a title bar, client, and other objects contained in a window. The role * is supported automatically by MS Windows. */ @@ -204,18 +204,17 @@ enum Role { * Represents a cell within a table. It is used for html:td, * xul:tree cell and xul:listcell. Also, see TABLE. */ CELL = 29, /** * Represents a link to something else. This object might look like text or * a graphic, but it acts like a button. It is used for - * xul:label@class="text-link", html:a, html:area, - * xforms:trigger@appearance="minimal". + * xul:label@class="text-link", html:a, html:area. */ LINK = 30, /** * Displays a Help topic in the form of a ToolTip or Help balloon. */ HELPBALLOON = 31, @@ -271,35 +270,34 @@ enum Role { /** * Represents a picture. Is is used for xul:image, html:img. */ GRAPHIC = 40, /** * Represents read-only text, such as labels for other controls or * instructions in a dialog box. Static text cannot be modified or selected. - * Is is used for xul:label, xul:description, html:label, role="label", - * or xforms:output. + * Is is used for xul:label, xul:description, html:label, role="label". */ STATICTEXT = 41, /** * Represents selectable text that allows edits or is designated read-only. */ TEXT_LEAF = 42, /** * Represents a push button control. It is used for xul:button, html:button, - * role="button", xforms:trigger, xforms:submit. + * role="button". */ PUSHBUTTON = 43, /** * Represents a check box control. It is used for xul:checkbox, - * html:input@type="checkbox", role="checkbox", boolean xforms:input. + * html:input@type="checkbox", role="checkbox". */ CHECKBUTTON = 44, /** * Represents an option button, also called a radio button. It is one of a * group of mutually exclusive options. All objects sharing a single parent * that have this attribute are assumed to be part of single mutually * exclusive group. It is used for xul:radio, html:input@type="radio", @@ -310,17 +308,17 @@ enum Role { /** * Represents a combo box; an edit control with an associated list box that * provides a set of predefined choices. It is used for html:select, * xul:menulist, role="combobox". */ COMBOBOX = 46, /** - * Represents the calendar control. It is used for date xforms:input. + * Represents the calendar control. */ DROPLIST = 47, /** * Represents a progress bar, dynamically showing the user the percent * complete of an operation in progress. It is used for xul:progressmeter, * role="progressbar". */ @@ -335,17 +333,17 @@ enum Role { * Represents a hot-key field that allows the user to enter a combination or * sequence of keystrokes. */ HOTKEYFIELD = 50, /** * Represents a slider, which allows the user to adjust a setting in given * increments between minimum and maximum values. It is used by xul:scale, - * role="slider", xforms:range. + * role="slider". */ SLIDER = 51, /** * Represents a spin box, which is a control that allows the user to increment * or decrement the value displayed in a separate "buddy" control associated * with the spin box. It is used for xul:spinbuttons. */
--- a/accessible/src/base/Statistics.h +++ b/accessible/src/base/Statistics.h @@ -26,20 +26,14 @@ namespace statistics { { Telemetry::Accumulate(Telemetry::A11Y_ISIMPLEDOM_USAGE_FLAG, true); } /** * Report that IAccessibleTable has been used. */ inline void IAccessibleTableUsed() { Telemetry::Accumulate(Telemetry::A11Y_IATABLE_USAGE_FLAG, true); } - /** - * Report that XForms accessibility has been instantiated. - */ - inline void XFormsAccessibleUsed() - { Telemetry::Accumulate(Telemetry::A11Y_XFORMS_USAGE_FLAG, true); } - } // namespace statistics } // namespace a11y } // namespace mozilla #endif
--- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -19,18 +19,16 @@ #include "HTMLSelectAccessible.h" #include "HTMLTableAccessibleWrap.h" #include "HyperTextAccessibleWrap.h" #include "nsAccessiblePivot.h" #include "nsAccUtils.h" #include "nsARIAMap.h" #include "nsEventShell.h" #include "nsIAccessibleProvider.h" -#include "nsXFormsFormControlsAccessible.h" -#include "nsXFormsWidgetsAccessible.h" #include "OuterDocAccessible.h" #include "Role.h" #include "RootAccessibleWrap.h" #include "States.h" #include "Statistics.h" #include "TextLeafAccessibleWrap.h" #ifdef MOZ_ACCESSIBILITY_ATK @@ -1242,93 +1240,16 @@ nsAccessibilityService::CreateAccessible break; case nsIAccessibleProvider::XULToolbarButton: accessible = new XULToolbarButtonAccessible(aContent, aDoc); break; #endif // MOZ_XUL - // XForms elements - case nsIAccessibleProvider::XFormsContainer: - accessible = new nsXFormsContainerAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsLabel: - accessible = new nsXFormsLabelAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsOutput: - accessible = new nsXFormsOutputAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsTrigger: - accessible = new nsXFormsTriggerAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsInput: - accessible = new nsXFormsInputAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsInputBoolean: - accessible = new nsXFormsInputBooleanAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsInputDate: - accessible = new nsXFormsInputDateAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsSecret: - accessible = new nsXFormsSecretAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsSliderRange: - accessible = new nsXFormsRangeAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsSelect: - accessible = new nsXFormsSelectAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsChoices: - accessible = new nsXFormsChoicesAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsSelectFull: - accessible = new nsXFormsSelectFullAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsItemCheckgroup: - accessible = new nsXFormsItemCheckgroupAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsItemRadiogroup: - accessible = new nsXFormsItemRadiogroupAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsSelectCombobox: - accessible = new nsXFormsSelectComboboxAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsItemCombobox: - accessible = new nsXFormsItemComboboxAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsDropmarkerWidget: - accessible = new nsXFormsDropmarkerWidgetAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsCalendarWidget: - accessible = new nsXFormsCalendarWidgetAccessible(aContent, aDoc); - break; - - case nsIAccessibleProvider::XFormsComboboxPopupWidget: - accessible = new nsXFormsComboboxPopupWidgetAccessible(aContent, aDoc); - break; - default: return nullptr; } NS_IF_ADDREF(accessible); return accessible; }
--- a/accessible/src/jsat/AccessFu.jsm +++ b/accessible/src/jsat/AccessFu.jsm @@ -111,16 +111,17 @@ this.AccessFu = { Logger.info('disable'); this.chromeWin.document.removeChild(this.stylesheet); for each (let mm in Utils.getAllMessageManagers(this.chromeWin)) mm.sendAsyncMessage('AccessFu:Stop'); Input.detach(); + this.touchAdapter.detach(this.chromeWin); this.chromeWin.removeEventListener('TabOpen', this); this.chromeWin.removeEventListener('TabSelect', this); Services.obs.removeObserver(this, 'remote-browser-frame-shown'); Services.obs.removeObserver(this, 'Accessibility:NextObject'); Services.obs.removeObserver(this, 'Accessibility:PreviousObject'); Services.obs.removeObserver(this, 'Accessibility:Focus');
deleted file mode 100644 --- a/accessible/src/xforms/Makefile.in +++ /dev/null @@ -1,61 +0,0 @@ -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DEPTH = @DEPTH@ -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -MODULE = accessibility -LIBRARY_NAME = accessibility_xforms_s -LIBXUL_LIBRARY = 1 - - - -CPPSRCS = \ - nsXFormsAccessible.cpp \ - nsXFormsFormControlsAccessible.cpp \ - nsXFormsWidgetsAccessible.cpp \ - $(NULL) - -# we don't want the shared lib, but we want to force the creation of a static lib. -FORCE_STATIC_LIB = 1 - -include $(topsrcdir)/config/rules.mk - -LOCAL_INCLUDES = \ - -I$(srcdir) \ - -I$(srcdir)/../base \ - -I$(srcdir)/../generic \ - -I$(srcdir)/../html \ - $(NULL) - -ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) -LOCAL_INCLUDES += \ - -I$(srcdir)/../atk \ - $(NULL) -else -ifeq ($(MOZ_WIDGET_TOOLKIT),windows) -LOCAL_INCLUDES += \ - -I$(srcdir)/../msaa \ - $(NULL) -else -ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) -LOCAL_INCLUDES += \ - -I$(srcdir)/../mac \ - $(NULL) -else -LOCAL_INCLUDES += \ - -I$(srcdir)/../other \ - $(NULL) -endif -endif -endif - -ifneq ($(A11Y_LOG),0) - DEFINES += -DA11Y_LOG -endif
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsAccessible.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "nsXFormsAccessible.h" - -#include "nsAccessibilityService.h" -#include "nsAccUtils.h" -#include "DocAccessible.h" -#include "nsTextEquivUtils.h" -#include "Role.h" -#include "States.h" -#include "Statistics.h" - -#include "nscore.h" -#include "nsServiceManagerUtils.h" -#include "nsIDOMElement.h" -#include "nsIDOMNodeList.h" -#include "nsIEditor.h" -#include "nsIMutableArray.h" -#include "nsIXFormsUtilityService.h" -#include "nsIPlaintextEditor.h" -#include "nsINodeList.h" - -using namespace mozilla::a11y; - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsAccessibleBase -//////////////////////////////////////////////////////////////////////////////// - -nsIXFormsUtilityService *nsXFormsAccessibleBase::sXFormsService = nullptr; - -nsXFormsAccessibleBase::nsXFormsAccessibleBase() -{ - if (!sXFormsService) { - nsresult rv = CallGetService("@mozilla.org/xforms-utility-service;1", - &sXFormsService); - if (NS_FAILED(rv)) - NS_WARNING("No XForms utility service."); - } - statistics::XFormsAccessibleUsed(); -} - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsAccessible:: - nsXFormsAccessible(nsIContent* aContent, DocAccessible* aDoc) : - HyperTextAccessibleWrap(aContent, aDoc) -{ -} - -nsresult -nsXFormsAccessible::GetBoundChildElementValue(const nsAString& aTagName, - nsAString& aValue) -{ - NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE); - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsINodeList* nodes = mContent->ChildNodes(); - - uint32_t length; - nsresult rv = nodes->GetLength(&length); - NS_ENSURE_SUCCESS(rv, rv); - - for (uint32_t index = 0; index < length; index++) { - nsIContent* content = nodes->Item(index); - if (content->NodeInfo()->Equals(aTagName) && - content->NodeInfo()->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) { - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(content)); - return sXFormsService->GetValue(DOMNode, aValue); - } - } - - aValue.Truncate(); - return NS_OK; -} - -void -nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode) -{ - nsCOMPtr<nsIDOMNode> container(aContainerNode); - if (!container) - container = do_QueryInterface(mContent); - - nsCOMPtr<nsIDOMNodeList> children; - sXFormsService->GetSelectChildrenFor(container, getter_AddRefs(children)); - - if (!children) - return; - - uint32_t length = 0; - children->GetLength(&length); - - for (uint32_t index = 0; index < length; index++) { - nsCOMPtr<nsIDOMNode> DOMChild; - children->Item(index, getter_AddRefs(DOMChild)); - if (!DOMChild) - continue; - - nsCOMPtr<nsIContent> child(do_QueryInterface(DOMChild)); - Accessible* accessible = - GetAccService()->GetOrCreateAccessible(child, mDoc); - if (!accessible) - continue; - - AppendChild(accessible); - } -} - -uint64_t -nsXFormsAccessible::NativeState() -{ - NS_ENSURE_TRUE(sXFormsService, 0); - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - bool isReadonly = false; - nsresult rv = sXFormsService->IsReadonly(DOMNode, &isReadonly); - NS_ENSURE_SUCCESS(rv, 0); - - bool isRequired = false; - rv = sXFormsService->IsRequired(DOMNode, &isRequired); - NS_ENSURE_SUCCESS(rv, 0); - - bool isValid = false; - rv = sXFormsService->IsValid(DOMNode, &isValid); - NS_ENSURE_SUCCESS(rv, 0); - - uint64_t states = HyperTextAccessibleWrap::NativeState(); - - if (NativelyUnavailable()) - states |= states::UNAVAILABLE; - - if (isReadonly) - states |= states::READONLY; - - if (isRequired) - states |= states::REQUIRED; - - if (!isValid) - states |= states::INVALID; - - return states; -} - -bool -nsXFormsAccessible::NativelyUnavailable() const -{ - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - bool isRelevant = false; - sXFormsService->IsRelevant(DOMNode, &isRelevant); - return !isRelevant; -} - -ENameValueFlag -nsXFormsAccessible::NativeName(nsString& aName) -{ - // search the xforms:label element - GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName); - return eNameOK; -} - -void -nsXFormsAccessible::Description(nsString& aDescription) -{ - nsTextEquivUtils:: - GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby, - aDescription); - - if (aDescription.IsEmpty()) - GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription); -} - -void -nsXFormsAccessible::Value(nsString& aValue) -{ - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - sXFormsService->GetValue(DOMNode, aValue); -} - -bool -nsXFormsAccessible::CanHaveAnonChildren() -{ - return false; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsContainerAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsContainerAccessible:: - nsXFormsContainerAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsContainerAccessible::NativeRole() -{ - return roles::GROUPING; -} - -bool -nsXFormsContainerAccessible::CanHaveAnonChildren() -{ - return true; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsEditableAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsEditableAccessible:: - nsXFormsEditableAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -uint64_t -nsXFormsEditableAccessible::NativeState() -{ - uint64_t state = nsXFormsAccessible::NativeState(); - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - bool isReadonly = false; - nsresult rv = sXFormsService->IsReadonly(DOMNode, &isReadonly); - NS_ENSURE_SUCCESS(rv, state); - - if (!isReadonly) { - bool isRelevant = false; - rv = sXFormsService->IsRelevant(DOMNode, &isRelevant); - NS_ENSURE_SUCCESS(rv, state); - if (isRelevant) { - state |= states::EDITABLE | states::SELECTABLE_TEXT; - } - } - - nsCOMPtr<nsIEditor> editor = GetEditor(); - NS_ENSURE_TRUE(editor, state); - uint32_t flags; - editor->GetFlags(&flags); - if (flags & nsIPlaintextEditor::eEditorSingleLineMask) - state |= states::SINGLE_LINE; - else - state |= states::MULTI_LINE; - - return state; -} - -already_AddRefed<nsIEditor> -nsXFormsEditableAccessible::GetEditor() const -{ - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - nsCOMPtr<nsIEditor> editor; - sXFormsService->GetEditor(DOMNode, getter_AddRefs(editor)); - return editor.forget(); -} - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSelectableAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSelectableAccessible:: - nsXFormsSelectableAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsEditableAccessible(aContent, aDoc), mIsSelect1Element(false) -{ - mFlags |= eSelectAccessible; - mIsSelect1Element = - mContent->NodeInfo()->Equals(nsGkAtoms::select1); -} - -already_AddRefed<nsIArray> -nsXFormsSelectableAccessible::SelectedItems() -{ - nsCOMPtr<nsIMutableArray> selectedItems = - do_CreateInstance(NS_ARRAY_CONTRACTID); - if (!selectedItems) - return nullptr; - - nsresult rv; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - if (mIsSelect1Element) { - nsCOMPtr<nsIDOMNode> itemDOMNode; - rv = sXFormsService->GetSelectedItemForSelect1(DOMNode, - getter_AddRefs(itemDOMNode)); - if (NS_FAILED(rv) || !itemDOMNode || !mDoc) - return nullptr; - - nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode)); - nsIAccessible* item = mDoc->GetAccessible(itemNode); - if (item) - selectedItems->AppendElement(item, false); - - nsIMutableArray* items = nullptr; - selectedItems.forget(&items); - return items; - } - - nsCOMPtr<nsIDOMNodeList> itemNodeList; - rv = sXFormsService->GetSelectedItemsForSelect(DOMNode, - getter_AddRefs(itemNodeList)); - if (NS_FAILED(rv) || !itemNodeList || !mDoc) - return nullptr; - - uint32_t length = 0; - itemNodeList->GetLength(&length); - - for (uint32_t index = 0; index < length; index++) { - nsCOMPtr<nsIDOMNode> itemDOMNode; - itemNodeList->Item(index, getter_AddRefs(itemDOMNode)); - if (!itemDOMNode) - return nullptr; - - nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode)); - nsIAccessible* item = mDoc->GetAccessible(itemNode); - if (item) - selectedItems->AppendElement(item, false); - } - - nsIMutableArray* items = nullptr; - selectedItems.forget(&items); - return items; -} - -uint32_t -nsXFormsSelectableAccessible::SelectedItemCount() -{ - nsresult rv; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - - if (mIsSelect1Element) { - nsCOMPtr<nsIDOMNode> item; - rv = sXFormsService->GetSelectedItemForSelect1(DOMNode, - getter_AddRefs(item)); - return NS_SUCCEEDED(rv) && item ? 1 : 0; - } - - nsCOMPtr<nsIDOMNodeList> itemNodeList; - rv = sXFormsService->GetSelectedItemsForSelect(DOMNode, - getter_AddRefs(itemNodeList)); - if (NS_FAILED(rv) || !itemNodeList) - return 0; - - uint32_t length = 0; - itemNodeList->GetLength(&length); - return length; -} - -bool -nsXFormsSelectableAccessible::AddItemToSelection(uint32_t aIndex) -{ - nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex))); - if (!itemDOMNode) - return false; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (mIsSelect1Element) - sXFormsService->SetSelectedItemForSelect1(DOMNode, itemDOMNode); - else - sXFormsService->AddItemToSelectionForSelect(DOMNode, itemDOMNode); - - return true; -} - -bool -nsXFormsSelectableAccessible::RemoveItemFromSelection(uint32_t aIndex) -{ - nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex))); - if (!itemDOMNode) - return false; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (mIsSelect1Element) { - nsCOMPtr<nsIDOMNode> selItemDOMNode; - sXFormsService->GetSelectedItemForSelect1(DOMNode, - getter_AddRefs(selItemDOMNode)); - if (selItemDOMNode == itemDOMNode) - sXFormsService->SetSelectedItemForSelect1(DOMNode, nullptr); - - return true; - } - - sXFormsService->RemoveItemFromSelectionForSelect(DOMNode, itemDOMNode); - return true; -} - -Accessible* -nsXFormsSelectableAccessible::GetSelectedItem(uint32_t aIndex) -{ - if (!mDoc) - return nullptr; - - nsresult rv; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (mIsSelect1Element) { - if (aIndex != 0) - return nullptr; - - nsCOMPtr<nsIDOMNode> itemDOMNode; - rv = sXFormsService->GetSelectedItemForSelect1(DOMNode, - getter_AddRefs(itemDOMNode)); - if (NS_SUCCEEDED(rv) && itemDOMNode) { - nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode)); - return mDoc->GetAccessible(itemNode); - } - return nullptr; - } - - nsCOMPtr<nsIDOMNodeList> itemNodeList; - rv = sXFormsService->GetSelectedItemsForSelect(DOMNode, - getter_AddRefs(itemNodeList)); - if (NS_FAILED(rv) || !itemNodeList) - return nullptr; - - nsCOMPtr<nsIDOMNode> itemDOMNode; - itemNodeList->Item(aIndex, getter_AddRefs(itemDOMNode)); - - nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode)); - return mDoc->GetAccessible(itemNode); -} - -bool -nsXFormsSelectableAccessible::IsItemSelected(uint32_t aIndex) -{ - nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex))); - if (!itemDOMNode) - return false; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (mIsSelect1Element) { - nsCOMPtr<nsIDOMNode> selItemDOMNode; - sXFormsService->GetSelectedItemForSelect1(DOMNode, - getter_AddRefs(selItemDOMNode)); - return selItemDOMNode == itemDOMNode; - } - - bool isSelected = false; - sXFormsService->IsSelectItemSelected(DOMNode, itemDOMNode, &isSelected); - return isSelected; -} - -bool -nsXFormsSelectableAccessible::UnselectAll() -{ - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (mIsSelect1Element) - sXFormsService->SetSelectedItemForSelect1(DOMNode, nullptr); - - sXFormsService->ClearSelectionForSelect(DOMNode); - return true; -} - -bool -nsXFormsSelectableAccessible::SelectAll() -{ - if (mIsSelect1Element) - return false; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - sXFormsService->SelectAllItemsForSelect(DOMNode); - return true; -} - -nsIContent* -nsXFormsSelectableAccessible::GetItemByIndex(uint32_t* aIndex, - Accessible* aAccessible) -{ - Accessible* accessible = aAccessible ? aAccessible : this; - uint32_t childCount = accessible->ChildCount(); - for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) { - Accessible* child = accessible->GetChildAt(childIdx); - nsIContent* childContent = child->GetContent(); - nsINodeInfo *nodeInfo = childContent->NodeInfo(); - if (nodeInfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) { - if (nodeInfo->Equals(nsGkAtoms::item)) { - if (!*aIndex) - return childContent; - - --*aIndex; - } else if (nodeInfo->Equals(nsGkAtoms::choices)) { - nsIContent* itemContent = GetItemByIndex(aIndex, child); - if (itemContent) - return itemContent; - } - } - } - - return nullptr; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSelectableItemAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSelectableItemAccessible:: - nsXFormsSelectableItemAccessible(nsIContent* aContent, - DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -void -nsXFormsSelectableItemAccessible::Value(nsString& aValue) -{ - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - sXFormsService->GetValue(DOMNode, aValue); -} - -uint8_t -nsXFormsSelectableItemAccessible::ActionCount() -{ - return 1; -} - -NS_IMETHODIMP -nsXFormsSelectableItemAccessible::DoAction(uint8_t aIndex) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - DoCommand(); - return NS_OK; -} - -bool -nsXFormsSelectableItemAccessible::IsSelected() -{ - nsresult rv; - - nsINode* parent = mContent; - while ((parent = parent->GetParentNode())) { - nsCOMPtr<nsIContent> content(do_QueryInterface(parent)); - if (!content) - return false; - - nsCOMPtr<nsINodeInfo> nodeinfo = content->NodeInfo(); - if (!nodeinfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) - continue; - - nsCOMPtr<nsIDOMNode> select(do_QueryInterface(parent)); - if (!select) - continue; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - if (nodeinfo->Equals(nsGkAtoms::select)) { - bool isSelected = false; - rv = sXFormsService->IsSelectItemSelected(select, DOMNode, &isSelected); - return NS_SUCCEEDED(rv) && isSelected; - } - - if (nodeinfo->Equals(nsGkAtoms::select1)) { - nsCOMPtr<nsIDOMNode> selitem; - rv = sXFormsService->GetSelectedItemForSelect1(select, - getter_AddRefs(selitem)); - return NS_SUCCEEDED(rv) && (selitem == DOMNode); - } - } - - return false; -} -
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsAccessible.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _nsXFormsAccessible_H_ -#define _nsXFormsAccessible_H_ - -#include "HyperTextAccessibleWrap.h" -#include "nsIXFormsUtilityService.h" - -#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms" - -/** - * Utility class that provides access to nsIXFormsUtilityService. - */ -class nsXFormsAccessibleBase -{ -public: - nsXFormsAccessibleBase(); - -protected: - // Used in GetActionName() methods. - enum { eAction_Click = 0 }; - - // Service allows to get some xforms functionality. - static nsIXFormsUtilityService *sXFormsService; -}; - - -/** - * Every XForms element that is bindable to XForms model or is able to contain - * XForms hint and XForms label elements should have accessible object. This - * class is base class for accessible objects for these XForms elements. - */ -class nsXFormsAccessible : public HyperTextAccessibleWrap, - public nsXFormsAccessibleBase -{ -public: - nsXFormsAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - // Returns value of child xforms 'hint' element. - virtual void Description(nsString& aDescription); - - // Returns value of instance node that xforms element is bound to. - virtual void Value(nsString& aValue); - - // Returns state of xforms element taking into account state of instance node - // that it is bound to. - virtual uint64_t NativeState(); - virtual bool NativelyUnavailable() const; - - // Denies accessible nodes in anonymous content of xforms element by - // always returning false value. - virtual bool CanHaveAnonChildren(); - - -protected: - // Accessible - // Returns value of child xforms 'label' element. - virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE; - - // Returns value of first child xforms element by tagname that is bound to - // instance node. - nsresult GetBoundChildElementValue(const nsAString& aTagName, - nsAString& aValue); - - // Cache accessible child item/choices elements. For example, the method is - // used for full appearance select/select1 elements or for their child choices - // element. Note, those select/select1 elements that use native widget - // for representation don't use the method since their item/choices elements - // are hidden and therefore aren't accessible. - // - // @param aContainerNode - node that contains item elements - void CacheSelectChildren(nsIDOMNode *aContainerNode = nullptr); -}; - - -/** - * This class is accessible object for XForms elements that provide accessible - * object for itself as well for anonymous content. You should use this class - * if accessible XForms element is complex, i.e. it is composed from elements - * that should be accessible too. Especially for elements that have multiple - * areas that a user can interact with or multiple visual areas. For example, - * objects for XForms input[type="xsd:gMonth"] that contains combobox element - * to choose month. It has an entryfield, a drop-down button and a drop-down - * list, all of which need to be accessible. Another example would be - * an XForms upload element since it is constructed from textfield and - * 'pick up file' and 'clear file' buttons. - */ -class nsXFormsContainerAccessible : public nsXFormsAccessible -{ -public: - nsXFormsContainerAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - - // Allows accessible nodes in anonymous content of xforms element by - // always returning true value. - virtual bool CanHaveAnonChildren(); -}; - - -/** - * The class is base for accessible objects for XForms elements that have - * editable area. - */ -class nsXFormsEditableAccessible : public nsXFormsAccessible -{ -public: - nsXFormsEditableAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // HyperTextAccessible - virtual already_AddRefed<nsIEditor> GetEditor() const; - - // Accessible - virtual uint64_t NativeState(); -}; - - -/** - * The class is base for accessible objects for XForms select and XForms - * select1 elements. - */ -class nsXFormsSelectableAccessible : public nsXFormsEditableAccessible -{ -public: - nsXFormsSelectableAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // SelectAccessible - virtual already_AddRefed<nsIArray> SelectedItems(); - virtual uint32_t SelectedItemCount(); - virtual Accessible* GetSelectedItem(uint32_t aIndex); - virtual bool IsItemSelected(uint32_t aIndex); - virtual bool AddItemToSelection(uint32_t aIndex); - virtual bool RemoveItemFromSelection(uint32_t aIndex); - virtual bool SelectAll(); - virtual bool UnselectAll(); - -protected: - nsIContent* GetItemByIndex(uint32_t* aIndex, - Accessible* aAccessible = nullptr); - - bool mIsSelect1Element; -}; - - -/** - * The class is base for accessible objects for XForms item elements. - */ -class nsXFormsSelectableItemAccessible : public nsXFormsAccessible -{ -public: - nsXFormsSelectableItemAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - NS_IMETHOD DoAction(uint8_t aIndex); - - // Accessible - virtual void Value(nsString& aValue); - - // ActionAccessible - virtual uint8_t ActionCount(); - -protected: - bool IsSelected(); -}; - -#endif -
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "nsXFormsFormControlsAccessible.h" - -#include "nsTextEquivUtils.h" -#include "Role.h" -#include "States.h" - -using namespace mozilla::a11y; - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsLabelAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsLabelAccessible:: - nsXFormsLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsLabelAccessible::NativeRole() -{ - return roles::LABEL; -} - -ENameValueFlag -nsXFormsLabelAccessible::NativeName(nsString& aName) -{ - // XXX Correct name calculation for this, see bug 453594. - return eNameOK; -} - -void -nsXFormsLabelAccessible::Description(nsString& aDescription) -{ - nsTextEquivUtils:: - GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby, - aDescription); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsOutputAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsOutputAccessible:: - nsXFormsOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsOutputAccessible::NativeRole() -{ - return roles::STATICTEXT; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsTriggerAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsTriggerAccessible:: - nsXFormsTriggerAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsTriggerAccessible::NativeRole() -{ - return roles::PUSHBUTTON; -} - -void -nsXFormsTriggerAccessible::Value(nsString& aValue) -{ - aValue.Truncate(); -} - -uint8_t -nsXFormsTriggerAccessible::ActionCount() -{ - return 1; -} - -NS_IMETHODIMP -nsXFormsTriggerAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex == eAction_Click) { - aName.AssignLiteral("press"); - return NS_OK; - } - return NS_ERROR_INVALID_ARG; -} - -NS_IMETHODIMP -nsXFormsTriggerAccessible::DoAction(uint8_t aIndex) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - DoCommand(); - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsInputAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsInputAccessible:: - nsXFormsInputAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsEditableAccessible(aContent, aDoc) -{ -} - -NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsInputAccessible, - Accessible, - nsIAccessibleText, - nsIAccessibleEditableText) - -role -nsXFormsInputAccessible::NativeRole() -{ - return roles::ENTRY; -} - -uint8_t -nsXFormsInputAccessible::ActionCount() -{ - return 1; -} - -NS_IMETHODIMP -nsXFormsInputAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - aName.AssignLiteral("activate"); - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsInputAccessible::DoAction(uint8_t aIndex) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - return sXFormsService->Focus(DOMNode); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsInputBooleanAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsInputBooleanAccessible:: - nsXFormsInputBooleanAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsInputBooleanAccessible::NativeRole() -{ - return roles::CHECKBUTTON; -} - -uint64_t -nsXFormsInputBooleanAccessible::NativeState() -{ - uint64_t state = nsXFormsAccessible::NativeState(); - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetValue(DOMNode, value); - NS_ENSURE_SUCCESS(rv, state); - - if (value.EqualsLiteral("true")) - state |= states::CHECKED; - - return state; -} - -uint8_t -nsXFormsInputBooleanAccessible::ActionCount() -{ - return 1; -} - -NS_IMETHODIMP -nsXFormsInputBooleanAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetValue(DOMNode, value); - NS_ENSURE_SUCCESS(rv, rv); - - if (value.EqualsLiteral("true")) - aName.AssignLiteral("uncheck"); - else - aName.AssignLiteral("check"); - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsInputBooleanAccessible::DoAction(uint8_t aIndex) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - DoCommand(); - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsInputDateAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsInputDateAccessible:: - nsXFormsInputDateAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsContainerAccessible(aContent, aDoc) -{ -} - -role -nsXFormsInputDateAccessible::NativeRole() -{ - return roles::DROPLIST; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSecretAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSecretAccessible:: - nsXFormsSecretAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsInputAccessible(aContent, aDoc) -{ -} - -role -nsXFormsSecretAccessible::NativeRole() -{ - return roles::PASSWORD_TEXT; -} - -uint64_t -nsXFormsSecretAccessible::NativeState() -{ - return nsXFormsInputAccessible::NativeState() | states::PROTECTED; -} - -void -nsXFormsSecretAccessible::Value(nsString& aValue) -{ - aValue.Truncate(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsRangeAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsRangeAccessible:: - nsXFormsRangeAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsRangeAccessible::NativeRole() -{ - return roles::SLIDER; -} - -uint64_t -nsXFormsRangeAccessible::NativeState() -{ - uint64_t state = nsXFormsAccessible::NativeState(); - - uint32_t isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsInRange(DOMNode, &isInRange); - NS_ENSURE_SUCCESS(rv, state); - - if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE) - state |= states::INVALID; - - return state; -} - -NS_IMETHODIMP -nsXFormsRangeAccessible::GetMaximumValue(double *aMaximumValue) -{ - NS_ENSURE_ARG_POINTER(aMaximumValue); - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetRangeEnd(DOMNode, value); - NS_ENSURE_SUCCESS(rv, rv); - - nsresult error = NS_OK; - *aMaximumValue = value.ToDouble(&error); - return error; -} - -NS_IMETHODIMP -nsXFormsRangeAccessible::GetMinimumValue(double *aMinimumValue) -{ - NS_ENSURE_ARG_POINTER(aMinimumValue); - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetRangeStart(DOMNode, value); - NS_ENSURE_SUCCESS(rv, rv); - - nsresult error = NS_OK; - *aMinimumValue = value.ToDouble(&error); - return error; -} - -NS_IMETHODIMP -nsXFormsRangeAccessible::GetMinimumIncrement(double *aMinimumIncrement) -{ - NS_ENSURE_ARG_POINTER(aMinimumIncrement); - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetRangeStep(DOMNode, value); - NS_ENSURE_SUCCESS(rv, rv); - - nsresult error = NS_OK; - *aMinimumIncrement = value.ToDouble(&error); - return error; -} - -NS_IMETHODIMP -nsXFormsRangeAccessible::GetCurrentValue(double *aCurrentValue) -{ - NS_ENSURE_ARG_POINTER(aCurrentValue); - - nsAutoString value; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->GetValue(DOMNode, value); - NS_ENSURE_SUCCESS(rv, rv); - - nsresult error = NS_OK; - *aCurrentValue = value.ToDouble(&error); - return error; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSelectAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSelectAccessible:: - nsXFormsSelectAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsContainerAccessible(aContent, aDoc) -{ -} - -uint64_t -nsXFormsSelectAccessible::NativeState() -{ - uint64_t state = nsXFormsContainerAccessible::NativeState(); - - uint32_t isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsInRange(DOMNode, &isInRange); - NS_ENSURE_SUCCESS(rv, state); - - if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE) - state |= states::INVALID; - - return state; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsChoicesAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsChoicesAccessible:: - nsXFormsChoicesAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsChoicesAccessible::NativeRole() -{ - return roles::GROUPING; -} - -void -nsXFormsChoicesAccessible::Value(nsString& aValue) -{ - aValue.Truncate(); -} - -void -nsXFormsChoicesAccessible::CacheChildren() -{ - CacheSelectChildren(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSelectFullAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSelectFullAccessible:: - nsXFormsSelectFullAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsSelectableAccessible(aContent, aDoc) -{ -} - -role -nsXFormsSelectFullAccessible::NativeRole() -{ - return roles::GROUPING; -} - -void -nsXFormsSelectFullAccessible::CacheChildren() -{ - CacheSelectChildren(); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsItemCheckgroupAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsItemCheckgroupAccessible:: - nsXFormsItemCheckgroupAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsSelectableItemAccessible(aContent, aDoc) -{ -} - -role -nsXFormsItemCheckgroupAccessible::NativeRole() -{ - return roles::CHECKBUTTON; -} - -uint64_t -nsXFormsItemCheckgroupAccessible::NativeState() -{ - uint64_t state = nsXFormsSelectableItemAccessible::NativeState(); - - if (IsSelected()) - state |= states::CHECKED; - - return state; -} - -NS_IMETHODIMP -nsXFormsItemCheckgroupAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - if (IsSelected()) - aName.AssignLiteral("uncheck"); - else - aName.AssignLiteral("check"); - - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsItemRadiogroupAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsItemRadiogroupAccessible:: - nsXFormsItemRadiogroupAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsSelectableItemAccessible(aContent, aDoc) -{ -} - -role -nsXFormsItemRadiogroupAccessible::NativeRole() -{ - return roles::RADIOBUTTON; -} - -uint64_t -nsXFormsItemRadiogroupAccessible::NativeState() -{ - uint64_t state = nsXFormsSelectableItemAccessible::NativeState(); - - if (IsSelected()) - state |= states::CHECKED; - - return state; -} - -NS_IMETHODIMP -nsXFormsItemRadiogroupAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - aName.AssignLiteral("select"); - return NS_OK; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsSelectComboboxAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsSelectComboboxAccessible:: - nsXFormsSelectComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsSelectableAccessible(aContent, aDoc) -{ -} - -role -nsXFormsSelectComboboxAccessible::NativeRole() -{ - return roles::COMBOBOX; -} - -uint64_t -nsXFormsSelectComboboxAccessible::NativeState() -{ - uint64_t state = nsXFormsSelectableAccessible::NativeState(); - - bool isOpen = false; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen); - NS_ENSURE_SUCCESS(rv, state); - - if (isOpen) - state |= states::EXPANDED; - else - state |= states::COLLAPSED; - - return state | states::HASPOPUP; -} - -uint64_t -nsXFormsSelectComboboxAccessible::NativeInteractiveState() const -{ - return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE; -} - -bool -nsXFormsSelectComboboxAccessible::CanHaveAnonChildren() -{ - return true; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsItemComboboxAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsItemComboboxAccessible:: - nsXFormsItemComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) : - nsXFormsSelectableItemAccessible(aContent, aDoc) -{ -} - -role -nsXFormsItemComboboxAccessible::NativeRole() -{ - return roles::LISTITEM; -} - -uint64_t -nsXFormsItemComboboxAccessible::NativeState() -{ - uint64_t state = nsXFormsSelectableItemAccessible::NativeState(); - if (IsSelected()) - state |= states::SELECTED; - - return state; -} - -uint64_t -nsXFormsItemComboboxAccessible::NativeInteractiveState() const -{ - return NativelyUnavailable() ? - states::UNAVAILABLE : states::FOCUSABLE | states::SELECTABLE; -} - -NS_IMETHODIMP -nsXFormsItemComboboxAccessible::GetActionName(uint8_t aIndex, nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - aName.AssignLiteral("select"); - return NS_OK; -} -
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h +++ /dev/null @@ -1,294 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _nsXFormsFormControlsAccessible_H_ -#define _nsXFormsFormControlsAccessible_H_ - -#include "nsXFormsAccessible.h" - -/** - * Accessible object for xforms:label. - */ - -class nsXFormsLabelAccessible : public nsXFormsAccessible -{ -public: - nsXFormsLabelAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual void Description(nsString& aDescription); - virtual mozilla::a11y::role NativeRole(); - -protected: - // Accessible - virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE; -}; - -/** - * Accessible object for xforms:output. - */ - -class nsXFormsOutputAccessible : public nsXFormsAccessible -{ -public: - nsXFormsOutputAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); -}; - -/** - * Accessible object for xforms:trigger and xforms:submit. - */ - -class nsXFormsTriggerAccessible : public nsXFormsAccessible -{ -public: - nsXFormsTriggerAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - NS_IMETHOD DoAction(uint8_t aIndex); - - // Accessible - virtual void Value(nsString& aValue); - virtual mozilla::a11y::role NativeRole(); - - // ActionAccessible - virtual uint8_t ActionCount(); -}; - -/** - * Accessible object for xforms:input and xforms:textarea. - */ - -class nsXFormsInputAccessible : public nsXFormsEditableAccessible -{ -public: - nsXFormsInputAccessible(nsIContent* aContent, DocAccessible* aDoc); - - NS_DECL_ISUPPORTS_INHERITED - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - NS_IMETHOD DoAction(uint8_t aIndex); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - - // ActionAccessible - virtual uint8_t ActionCount(); -}; - -/** - * Accessible object for xforms:input[type="xsd:boolean"]. - */ - -class nsXFormsInputBooleanAccessible : public nsXFormsAccessible -{ -public: - nsXFormsInputBooleanAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - NS_IMETHOD DoAction(uint8_t aIndex); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); - - // ActionAccessible - virtual uint8_t ActionCount(); -}; - -/** - * Accessible object for xforms:input[type="xsd:date"]. - */ - -class nsXFormsInputDateAccessible : public nsXFormsContainerAccessible -{ -public: - nsXFormsInputDateAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); -}; - -/** - * Accessible object for xforms:secret. - */ - -class nsXFormsSecretAccessible : public nsXFormsInputAccessible -{ -public: - nsXFormsSecretAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual void Value(nsString& aValue); - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); -}; - - -/** - * Accessible object for xforms:range. - */ - -class nsXFormsRangeAccessible : public nsXFormsAccessible -{ -public: - nsXFormsRangeAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // nsIAccessibleValue - NS_IMETHOD GetMaximumValue(double *aMaximumValue); - NS_IMETHOD GetMinimumValue(double *aMinimumValue); - NS_IMETHOD GetMinimumIncrement(double *aMinimumIncrement); - NS_IMETHOD GetCurrentValue(double *aCurrentValue); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); -}; - - -/** - * Accessible object for xforms:select and xforms:select1 that are implemented - * using host document's native widget. - */ - -class nsXFormsSelectAccessible : public nsXFormsContainerAccessible -{ -public: - nsXFormsSelectAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual uint64_t NativeState(); -}; - - -/** - * Accessible object for xforms:choices. - */ - -class nsXFormsChoicesAccessible : public nsXFormsAccessible -{ -public: - nsXFormsChoicesAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // nsIAccessible - - // Accessible - virtual void Value(nsString& aValue); - virtual mozilla::a11y::role NativeRole(); - -protected: - // Accessible - virtual void CacheChildren(); -}; - - -/** - * Accessible object for xforms:select/xforms:select1 of full appearance that - * may be represented by group of checkboxes or radiogroup. - */ - -class nsXFormsSelectFullAccessible : public nsXFormsSelectableAccessible -{ -public: - nsXFormsSelectFullAccessible(nsIContent* aContent, DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - -protected: - // Accessible - virtual void CacheChildren(); -}; - - -/** - * Accessible object for a xforms:item when it is represented by a checkbox. - * This occurs when the item is contained in a xforms:select with full - * appearance. Such a xforms:select is represented by a checkgroup. - */ - -class nsXFormsItemCheckgroupAccessible : public nsXFormsSelectableItemAccessible -{ -public: - nsXFormsItemCheckgroupAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); -}; - - -/** - * Accessible object for a xforms:item when it is represented by a radiobutton. - * This occurs when the item is contained in a xforms:select1 with full - * appearance. Such a xforms:select1 is represented as a radiogroup. - */ - -class nsXFormsItemRadiogroupAccessible : public nsXFormsSelectableItemAccessible -{ -public: - nsXFormsItemRadiogroupAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); -}; - - -/** - * Accessible object for xforms:select1 of minimal appearance that is - * represented by combobox. - */ - -class nsXFormsSelectComboboxAccessible : public nsXFormsSelectableAccessible -{ -public: - nsXFormsSelectComboboxAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); - virtual uint64_t NativeInteractiveState() const; - virtual bool CanHaveAnonChildren(); -}; - - -/** - * Accessible object for xforms:item element when it is represented by a - * listitem. This occurs when the item is contained in a xforms:select with - * minimal appearance. Such a xforms:select is represented by a combobox. - */ - -class nsXFormsItemComboboxAccessible : public nsXFormsSelectableItemAccessible -{ -public: - nsXFormsItemComboboxAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); - virtual uint64_t NativeInteractiveState() const; -}; - -#endif -
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "nsXFormsWidgetsAccessible.h" - -#include "Role.h" -#include "States.h" - -using namespace mozilla::a11y; - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsDropmarkerWidgetAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsDropmarkerWidgetAccessible:: - nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent, - DocAccessible* aDoc) : - LeafAccessible(aContent, aDoc) -{ -} - -role -nsXFormsDropmarkerWidgetAccessible::NativeRole() -{ - return roles::PUSHBUTTON; -} - -uint64_t -nsXFormsDropmarkerWidgetAccessible::NativeState() -{ - bool isOpen = false; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen); - NS_ENSURE_SUCCESS(rv, 0); - - return isOpen ? states::PRESSED: 0; -} - -uint8_t -nsXFormsDropmarkerWidgetAccessible::ActionCount() -{ - return 1; -} - -NS_IMETHODIMP -nsXFormsDropmarkerWidgetAccessible::GetActionName(uint8_t aIndex, - nsAString& aName) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - bool isOpen = false; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen); - NS_ENSURE_SUCCESS(rv, rv); - - if (isOpen) - aName.AssignLiteral("close"); - else - aName.AssignLiteral("open"); - - return NS_OK; -} - -NS_IMETHODIMP -nsXFormsDropmarkerWidgetAccessible::DoAction(uint8_t aIndex) -{ - if (aIndex != eAction_Click) - return NS_ERROR_INVALID_ARG; - - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - return sXFormsService->ToggleDropmarkerState(DOMNode); -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsCalendarWidgetAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsCalendarWidgetAccessible:: - nsXFormsCalendarWidgetAccessible(nsIContent* aContent, DocAccessible* aDoc) : - AccessibleWrap(aContent, aDoc) -{ -} - -role -nsXFormsCalendarWidgetAccessible::NativeRole() -{ - return roles::CALENDAR; -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsXFormsComboboxPopupWidgetAccessible -//////////////////////////////////////////////////////////////////////////////// - -nsXFormsComboboxPopupWidgetAccessible:: - nsXFormsComboboxPopupWidgetAccessible(nsIContent* aContent, - DocAccessible* aDoc) : - nsXFormsAccessible(aContent, aDoc) -{ -} - -role -nsXFormsComboboxPopupWidgetAccessible::NativeRole() -{ - return roles::LIST; -} - -uint64_t -nsXFormsComboboxPopupWidgetAccessible::NativeState() -{ - uint64_t state = nsXFormsAccessible::NativeState(); - - bool isOpen = false; - nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); - nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen); - NS_ENSURE_SUCCESS(rv, state); - - if (isOpen) - state = states::FLOATING; - else - state = states::INVISIBLE; - - return state; -} - -uint64_t -nsXFormsComboboxPopupWidgetAccessible::NativeInteractiveState() const -{ - return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE; -} - -ENameValueFlag -nsXFormsComboboxPopupWidgetAccessible::NativeName(nsString& aName) -{ - // Override nsXFormsAccessible::GetName() to prevent name calculation by - // XForms rules. - return eNameOK; -} - -void -nsXFormsComboboxPopupWidgetAccessible::Description(nsString& aDescription) -{ - aDescription.Truncate(); -} - -void -nsXFormsComboboxPopupWidgetAccessible::Value(nsString& aValue) -{ - aValue.Truncate(); -} - -void -nsXFormsComboboxPopupWidgetAccessible::CacheChildren() -{ - nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetParentNode()); - // Parent node must be an xforms:select1 element. - CacheSelectChildren(parent); -} -
deleted file mode 100644 --- a/accessible/src/xforms/nsXFormsWidgetsAccessible.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _nsXFormsWidgetsAccessible_H_ -#define _nsXFormsWidgetsAccessible_H_ - -#include "BaseAccessibles.h" -#include "nsXFormsAccessible.h" - -/** - * Accessible object for dropmarker widget that is used inside xforms elements - * of combobox representation. For example, these are xforms:select1, - * xforms:input[type="xsd:date"]. - */ -class nsXFormsDropmarkerWidgetAccessible : public mozilla::a11y::LeafAccessible, - public nsXFormsAccessibleBase -{ -public: - nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // nsIAccessible - NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); - NS_IMETHOD DoAction(uint8_t aIndex); - - // Accessible - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); - - // ActionAccessible - virtual uint8_t ActionCount(); -}; - - -/** - * Accessible object for calendar widget. It is used by xforms:input[xsd:date]. - */ -class nsXFormsCalendarWidgetAccessible : public AccessibleWrap -{ -public: - nsXFormsCalendarWidgetAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // Accessible - virtual mozilla::a11y::role NativeRole(); -}; - - -/** - * Accessible object for popup menu of minimal xforms select1 element that is - * represented by combobox. - */ -class nsXFormsComboboxPopupWidgetAccessible : public nsXFormsAccessible -{ -public: - nsXFormsComboboxPopupWidgetAccessible(nsIContent* aContent, - DocAccessible* aDoc); - - // Accessible - virtual void Description(nsString& aDescription); - virtual void Value(nsString& aValue); - virtual mozilla::a11y::role NativeRole(); - virtual uint64_t NativeState(); - virtual uint64_t NativeInteractiveState() const; - -protected: - // Accessible - virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE; - virtual void CacheChildren(); -}; - -#endif
--- a/b2g/chrome/content/forms.js +++ b/b2g/chrome/content/forms.js @@ -320,23 +320,23 @@ function getJSON(element) { case "time": case "datetime": case "datetime-local": type = typeLowerCase; break; } } - // Gecko supports the inputmode attribute on text fields (but not textareas). - // But it doesn't recognize "verbatim" and other modes that we're interested - // in in Gaia, and the inputmode property returns "auto" for any value - // that gecko does not support. So we must query the inputmode attribute - // with getAttribute() rather than just using the inputmode property here. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=746142 - let inputmode = element.getAttribute('inputmode'); + // Gecko has some support for @inputmode but behind a preference and + // it is disabled by default. + // Gaia is then using @x-inputmode has its proprietary way to set + // inputmode for fields. This shouldn't be used outside of pre-installed + // apps because the attribute is going to disappear as soon as a definitive + // solution will be find. + let inputmode = element.getAttribute('x-inputmode'); if (inputmode) { inputmode = inputmode.toLowerCase(); } else { inputmode = ''; } return { "type": type.toLowerCase(),
--- a/b2g/installer/Makefile.in +++ b/b2g/installer/Makefile.in @@ -33,16 +33,21 @@ JAREXT=.jar else JAREXT= endif DEFINES += -DJAREXT=$(JAREXT) include $(topsrcdir)/ipc/app/defs.mk DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) +# Set MSVC dlls version to package, if any. +ifdef WIN32_REDIST_DIR +DEFINES += -DMOZ_MSVC_REDIST=$(_MSC_VER) +endif + ifdef ENABLE_MARIONETTE DEFINES += -DENABLE_MARIONETTE=1 endif ifdef MOZ_PKG_MANIFEST_P MOZ_PKG_MANIFEST = package-manifest endif
--- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -61,34 +61,34 @@ @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@ #endif #ifdef XP_MACOSX @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/ #else @BINPATH@/@MOZ_CHILD_PROCESS_NAME@ #endif #ifdef XP_WIN32 -#ifndef MOZ_MEMORY -#if _MSC_VER == 1400 +#ifndef MOZ_DEBUG +#if MOZ_MSVC_REDIST == 1400 @BINPATH@/Microsoft.VC80.CRT.manifest @BINPATH@/msvcm80.dll @BINPATH@/msvcp80.dll @BINPATH@/msvcr80.dll -#elif _MSC_VER == 1500 +#elif MOZ_MSVC_REDIST == 1500 @BINPATH@/Microsoft.VC90.CRT.manifest @BINPATH@/msvcm90.dll @BINPATH@/msvcp90.dll @BINPATH@/msvcr90.dll -#elif _MSC_VER == 1600 +#elif MOZ_MSVC_REDIST == 1600 @BINPATH@/msvcp100.dll @BINPATH@/msvcr100.dll +#elif MOZ_MSVC_REDIST == 1700 +@BINPATH@/msvcp110.dll +@BINPATH@/msvcr110.dll #endif -#else -@BINPATH@/mozcrt19.dll -@BINPATH@/mozcpp19.dll #endif #endif #ifdef MOZ_SHARED_MOZGLUE @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@ #endif #ifdef ANDROID @BINPATH@/AndroidManifest.xml @BINPATH@/resources.arsc
--- a/b2g/installer/removed-files.in +++ b/b2g/installer/removed-files.in @@ -1,6 +1,10 @@ README.txt @DLL_PREFIX@mozutils@DLL_SUFFIX@ jssubloader/ #ifdef XP_MACOSX run-mozilla.sh -#endif \ No newline at end of file +#endif +#ifdef XP_WIN + mozcrt19.dll + mozcpp19.dll +#endif
index 4e873d381e355127b8700a8395699b39ecba3665..4f9061a09ac8759d90dc1e6c848d2f72537a2295 GIT binary patch literal 4172 zc$@)D5VP-zP)<h;3K|Lk000e1NJLTq003|R000mO1^@s6&J_C*0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU>?ny*JR9M5snF&;t<+{f$Tb;~o&~vNX zx#!$Wt<>tQhI7y9tV&BOl}Xbk1R0bKq6jLp%AhiXm?+_ZIOG6nXoiF+$|Q)&JO~JE z*uWkb_dI-i@Be+?57`Mqr_Q=--EXb``rh$lfA8;mp7(iPCQSH0zFu4sHFJhdOvKz3 zyNYMo#wwU*f0j`El67<h>l;1(zpWxZoM{tRPks2k`Ypf5&|^EpD6xCbBwf0Y-O;o3 zrQh>DoNU>vCYjx0PGV=zWRlq~La*Jd`^UsaMTL_vo}3&UzVh9;@yW5CU+ysBFO^OY zpRI6w$UtTM7F9S-FjP7{be7G1;DJ+KnDCI`+@FgC=l_fmqBhp|E8rd`SiY|;jZ=HY z{lxA0{wB^8wBTs&9RwXH#ERfE+)Ue8HNo{|V~6LxWF6D-KW;~mUsi{@#%eU)tw)Qn z3GJP&=n{({?GdAIpa*irAk-Qa^aedlCeuBD829%;y8Jnl#O^br)FxbccY39=WmcV0 zYJ1oyvkPVI>JHmyehnP@7EdxsY?m0NcHyel*;Vr9xmu0z^%AO|;-4W~x)_*0@!s$k zHu?A*Xl!VJUZ)$O=!gi!L`7q3@D{_i;4S;N1_h7!yOqupGrM-rGZ_j(V7$KbKJ9?9 zcssbFaBziT;PSVDyBZAcN&xiP-sp_^n~5N1js@@$x6J=Su{>#nSR3mb58j;55{f?Y zOjTX4?Z)BkdaQ}PgpYhOc-imBhTp+bgdV?*w;jJ#&9aLt8ivR~{M8{D=Putwx3m{3 zjUFnk9%`-O7wHVp@ZxxB^&Agy?%c3P$6Wkwn?G_gTPIrV<Eqw|EA@lvX5HWkGnK2T zErYeQeg<hgfCSl!#_i+8pPW|+ZOmq~4vN<IOq_Vh4@1weO)^RCK4oJgckX;NEF>i7 zQce!kYBdH12O*V8q19?ZeaOnnf>0<#eO(=PZr?8U_w`+Fu|UU%j9f_sxXdLm)f|Mm zw+5!BGccAC#4LLlPW%IgV}FC;$Xn2-z5)HgxpaREy6g=ocbs4x3*e)x&;E&r7TfU- zFIHx4tZ%HBWtR8x+Ei6VOE26AT+qIsk#j8{SMo3M%DI{kzoaZI-TET}j+Wz1hh!C5 zp6@Wg1s;d+p6h<h7aYPo!G0{-kcJfjCt)9w0mtw&aNh9))<m6yd&~u_Pq>K9doKMd zKxR2=;hcQM-RbQE4O2BHP6`tz!@!+sYGw0_EgIn)*9k(JL2SF|<2CVBGi;(qxaN=7 zgy8I1D@f|!L{GzP=;Y@?1flIa3~Ak~=&pSoRV9m6Mu}}0`+GaWw;#&8k_V+yg|4n{ zh&sC<>**z!8c-khBqbsD@@0b9PGDu&y=#{-C?H_jJr@d7MIwwpE(TZn4Pa2?{>$8v z2g8}gLlD#69D;aY4h*@Qcy~G$z(2TTyzl@(*2enA+Vhy(%)QkC*XSIa$|^)jX(770 zJD^Z1NOE*`b)fV{5l&plhjrk2xbG>(405MzE?cl=VHY8Y&W6L*Gx$3AB<U2s-f{{K zA?a8ZmcavbjmWeB^xu~|0$@U7+|HP|NG>`y0(-s*N7+?tsAUl_8AQCyW+RECayyLr zHfW@wkkq~3X_PMAJl!e^`+si2sls-P@+-11(EN9pO=_5oy>!>{0GSn<xE`u2Ag-MY z`Uuj)LPOt8-j|F)xdLtN9rWH}w0DS5P*_Ost^)NVIyx2?vwucyeFMZ2Da2wa0s{j2 zw{F=ojR$x$7F@<WXrrb=y=5Y_yUEHjR>9buI|NbF2V<V^J$TfY@(K(&-s1ywI`#Ym z09o5u0B2aoL<k~(<dQP0v1NY_Zda5+qtSrl3?vTTK3>r4bx^5PD6hN;zr7c+GA0iT zy-#w}hXNZc-FX??)9=83`vrWo?hropPJ_+nW7zEZG6Drt;Iw7W2!Mg#Ua<fS3k!QB zHa^P0+!g<_#ts+<c0t*`49xP(W<4#qoZ5SNnYb?M`wUIDzc5iy63?E)plwR4u;@f? z8d_@>LM;uWIRwnu2Q$qx8$0PPruJZz7yX?9%m@w&POqt}N2gdqdv`l3tE#bW>ox@V z2h`uLsN~D@=gklE^4ic_T~kMUd<&$qUi_Ss%f>`72yDM&F4A!1Z5R%|4*lMjpo@DB z>X1J`f6fEYEBSZha@Iq)Zzgm}(_zT+7$2bHiDw@G$lAsNIA?i6am29_I7elp<aQ<f zI0*~}1B^x^A8dU7<#MX)q0?z0k&01#s~lEA=kUe$Y`nZQzIZ%<_Fmpdj`}OAuLon3 z&j%v_ZrPuAKfuQbppm^G`$$ysdg%I+p%J@bpy^LT0Ccxt)|OCNiowReKqnQTsoc%1 z?_RohEPy8oV0mRQgw?d5iVHNq0w#S0{~TTaA#^s($AzC<d4PdIL1a+9sBdaUV{<D4 zgMwkda%Chf&1``{a3Cl+m@V=%@BZ_jD<UEz4b`>vXlQQ1-Buws`})=~2wYw;bjh>8 z-AIH<QVwI?DHyUn3Dir_?0gE^U9a#E%_<p<dkxz7=V3VKJU&4CWB>60K-M-EK#D9C z2QN0@Lkd<J?$pyFDlGuhGfv+FXy5@V6mm2)*5m#4r{TVr+^9{AVl==t9t#oR`8)z# zCPLDZL~gGQ+dLmfu;)|+dC!Gc%yEPqygDX8xm*tUKr=MGsZfhIK;0#P*-%f<xJzn= zSziTJmn#gt{=)zx!zs)+8cpbzt1MCu<U`vViNU+G$>KT)ULAqVgh^LL&uN9C<xSL- z4gvHF2tXGBEUT<WS$P%Q*RHLjW%=W9bn4{da`0aHu{Cajg4-2UxJBwDH|pmfpk)vY z6jkz23S#IZQCRjrQ|lG7xYwYGcyh=R=`z;;0L_jm(5HVn1dyc$U!_iK`|9vC3@hT= zq6Yx7w)@A>oCY?R0o<KggZbX+Xl-lZtw68W^DgvsI_+bt?2&r-5N+OKTHryn3R}hn z=ooqo{;m^o=lXllN;Z<!6cB(0a*0vsxw8cELDS$9ydGhx`C|ec80be|pA?FoOsFLR zP>EK8Q(whk^K8<q;8a(s?JIEop*%pPaM=pBZ?a3H)mWreH9|jd7z*JB(Dp<?-ue&7 z+uo!4LTIHS&~)0M?uHADvZY}gHg43lb&63`b{i!(%i-+mdUg2Y_TIQDltCP>3q00V zmfosFX?Z0?;vQ`F^XDPxGuJ>9J{cO?|I|SfpoyIhV|Drvux5&ELm%V!#^F6tn>Yu$ zqc#?R6YX|AW%tE_XEaCa)>_hrH1QV}fUG>+ez-;eHr6)bsl{yWE6Wm!z4qkc^U$AA z-`s}5!2#ad*uKX=_Vmh-b|e-4fqsxtxu&TVO9IDtp{vOPqy4ARVl8H0I4|0(kn!zI z1b9uy`q*^rNGlitkOCMZ3o?3pdmxiZ(I+i~Qknuq$JbD_SwkiEhq7xkL9l|N{cHLl zVo-X`$6S~rczP^=yyRC2UOZXydJ1|1Y2OQ{=lDU@y$+_q7~C#!gF#|9%gtkLV?}Kv zL8&2#<p|yus&{f-J%<7F*}NH~5LWi`@mb?d^@`dClvUNDrK1}Jzn2G?zLEzwTEh@^ z-!0?oEU;mhKEn~ZBTFm*A0|Ei>GmnhmZv<eNv(DpVSV>o;i0NEpfRdX!lqc!oJnjh zJ7KZ*OXt?@EkbDOHT3oOQV^r297tmks}Bs4b@caO+rewF{}(~bX3rTYzx0j;Acgzz zUp)~X5y$vFF!E@j1z=oU+~i?^%*w^$E_8QyLe@=|Cr+V74~4ROSRuSPWd?bLcq74o zVl03vwF-j@Iy~shg;MtI5Ijj3l#)<hX4OgTPua%rKVRCfOg?t{d(_g$d$sf?@`_5~ z=(1Y2*xJT*z0XGEUMm9KZ?SS-;dR`otU*=7T@;qyf~&wii$Tzx{(1;d)+U(cUHpC6 z68YfeMhahN(J5aq{sy|VMZfHU%#s+yg`tzJmL)%_VxUI5&;u2&pgzTdZIhR<v24z8 z8o^Fjd{RpJ6yb7N6O?Kte{#Z7h(Y-P!Rv!kr9keDMlAL}_dpsk8epL3a}ZU`N7==< za4z*_47M!7j!jdsHvAhNV9fF2UjXikE>BKLYA_l(LwC2Ry|c4jDC!UjJKEcXUG29- zJ)$$R{>}sa16_Lu`Z`nlB%&O#PN&wV9X-?(6CYJK7C;64)_(fUvR(<Kl3GZ+FGJS# zJ;b8(5Oow#sA~Y5#|Lq*y*Agu#YJ(e<_=0L>u~<kRUA5g8eYDESnIU`Eg}iN`~C+4 zS4);xhXS(FCSe!0M@D0jmDO?{;P(zthfji8(LEGN)1B4Tp^x%=qN$@~s7_*eqN)8l zbjPhn1~J1BKMH<)iCxkZ`TlYji`z`O?F`oTVbJ5B-Vg7-<1k;AoO`B}@qoh9iXf8q zlMAKbh1{q}(uXi|d#sO*8J)<F2I%YY0z%e50pE4A;I&~Pg4`!jI`J4hx9{Tt#+|rs z0Z0q^9i<R=Nv#C#WV^8Cy9d>LqNBa}#Bg1$R^8ER)OQmSV-Jr8s3vd0K0f9xBr-8N zDW4UJC~9nLL{m!xFLn(Br0bD+3l?nh_6snTRW%^5<Q8@xNQ3((e+bsCM^k$@%Bt&; zcb%-W<R<D{I&kC^olZG9pQE{x`5@*eH|P@ola9!Ihb)lptgcIVmJ;?57%qnm)#IP# z%ZAILl-z&*U=%tGabCcrPplIs%ad=e0uz-7=lM@sFcv(^IVc^EF)+-!n2Til91B*M zSedo4J~n3bQQByLRvVJ=g?A`E3p|N0x2D5s>$h+VOSYsDyH1td571quR2=UV3B5!e zZR>uMM8frK4gp*}7QjIQ*h>J#(k_U)glKJV=E2oBRr4AJkX=u|`~C<1j;q~z&tJ;J zmExO7Oi9J+wVt@s)<v%MHp<9CYn$6~;OGggbau&qX6n?L_fBGrhD)B%A9<4pq~7)j zf7c&+m6vA66O>9k@k@Q@6pBipg5iP#132bU8V~V(zsKe;NqD@CiIvBLcRxgCRm?TA z{fz}FEYf6RW!A>}*qG6W+3$OuCV&laj=abx@SoFZj1wK9xksOecVZTuyyQ^oa0L-Z z3ds73u{*uga+pmEIafY7VEyli0M4fQW|s2&o{R12Y~H9PnDpX|8FOq`e12-V{Yv91 zfhU~ZJy6%$IYOD)m+_U8a}15=58^9VO~{lbzGLQcJiuLE2QJqW+$E2Da;N0ojkE^b z&#Q-&?ZU&8#lK-@bH{{n4<ZXvp1P+=zXosg(HaX*ScJ*a1SVFV{{Qsvq<?iKev`0o z_!#cDijCj3J8s_?k7H1#5Xk9oy#0<~m74&+q7ci!lU7YQTj4O_xBokd#<DqV?*9Vl Wzh&#e7*Le}0000<MNUMnLSTZ`Aqr3c
index 973c4b0559d226df14824f4830c13c6ac057f0f5..b7365a9c6911301427ef88154a13b5ce92839301 GIT binary patch literal 6530 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
new file mode 100644 index 0000000000000000000000000000000000000000..0dbf602c732d74b1382a98fb8dddff8edf88a9dd GIT binary patch literal 556 zc%17D@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4(FKVEpXq;uvD#pX_m8<@klKCs_K@ z|CyVyC$Y=ikcrgw(09J&7AeBK?7vyjnLBFbk{bWyC7X{p6rIR&tdb16etLm~!N<vs z#sP2sf6RaS-@itmEm=TXg>8~^826>q6ZV8j9c`EwUZv+?xZ&8p?OF*uNpQ_V;hqa6 zF8p;mFRIa&$l$@F(!NG)$#liKoh)sP4u(9;4oNTA8on4E(GxvvzyMKlmtjI&z!phG zcTtbPD@uVNH42tnGOn__&aS=UH1WCM=a&D63tltwgJe!*EfVjvVR^Ncv2|C{v$C15 zHdr><PqX1_aKHPg->iVyA!o*qL+y3{9kVu<pPKf4@73_+2UC+0v@F*wo3_bsmsv&M zfqqv0n!p_QvZH_4?fy4E=c@6K)sGD<4RaO-I<!Da{)E7@LwmJOoqWASiz)qM?fm-t z{D--V-~al<KkMjs-PFA$mM5Gh$W4f2`+suJ0|8dfCpn?h{G*g3#SD7Czn*h@UqSl$ zeQ!U@t4!MywrWX2f0vMlt_Qz|e)D^lyoxOiDwnQnonqkC{5Jc@-_&DQ8~z)w`}v=J zlRdMkcv^1Qq~=VvM4-{{?ewOUFa%B56BDPEIyXcv;9#);+eXKv6SEv8mP|jmx?PyL qSwu~DsyI8_6mE{@8w!RwS&VyDJ<z$;>aPh*1q`09elF{r5}E+$VCT*N
index 507c627f765990037170bbb5244c7a3b686a59cb..7514317fedf29c162dea25a9e3fdcde262c9e30e GIT binary patch literal 723 zc$@*#0xbQBP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0007-Nkl<ZNQq<M zm11DPg=hXZHUwe^0@x6r87Q2tM<ys3WI*vr`AY>yW&dNtAUTj4bbTaQkbhX_|M9O? z|4)1`M!_I4kQ~Jp<Q<X*8`%F=1qFk|KynmYkaIu^rv)H6iY>_ACyCPnkQ~JpWbT&0 zX#q%%VhhrDisQ5ZBuB9YsoTVGS^$!x*n;FOqBt!8$x&=U;zkji7J%f4vH+-v3y5v7 z6$SC@gm78_lEYDafXw1Twt#KMKO@`t^+GRW*9iVc#vLczaasV9Lsy@$LFh5iJZm6k zMF}FHfKdEek*!@9Z83_4#UE`jEC7k2tLp^nO;{(g5onem);LI7E~f=_#hKolW?&6- zKbT<{jE?7jFbAsz>4{q_cqDC&q6XebPG2u?8MTuCO8-qOu*TW%jc^(cl7kp-{vW94 zQsyQFOM<B=xJQyHbF-XB#4^6S6K_F+VfuSL48uWUAUTj4pxWEn+Z5bDdWlM=S(}yE zGB(SFhA!rLG5MAq*q{k-)!>FtdZ!K+n|#~uf7lY<$C+E@LTWE+vXYb!fEu{cH_Idh z&*y$S^R6pON&>NG+;#pRyny>HNKL~vEpD<hTElfM!Q^$4xj}QeKF+=G2~RC^A9(%` zn#c7qWrI|9;|(n#qH{73FhVgC5HkZYOa3lZh4|&-RsOR$ek`~X@_)hIkpKR(Ievh| zKyn~8P_;}j{rD^ZDPjX+PLLE33jncj<P=%+uvx-g{?j==0P$N8J9>tkB}fjch8L;_ zq?ZYw1t6DjKs5*fu{aQeWMsqoWjrD#%VtJSmCXpBB<lqdgUX3R)$&61G86Iv$jj_d z7x4fw9}x3%@-qvD_Q|LOcgZM&*dQ^e91m12J5(=<4*;PvQ?5y<BO?F+002ovPDHLk FV1nGsHGu#C
--- a/browser/themes/gnomestripe/downloads/downloads.css +++ b/browser/themes/gnomestripe/downloads/downloads.css @@ -184,30 +184,32 @@ toolbar[iconsize="small"] #downloads-ind 0, 16, 16, 0) center no-repeat; } toolbar[iconsize="large"] #downloads-indicator-icon { background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 24, 24, 0) center no-repeat; } -#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon { - background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 16, 32, 32, 16) center no-repeat; +toolbar[iconsize="small"] #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon { + background-image: url("chrome://browser/skin/downloads/download-glow-small.png"); +} + +toolbar[iconsize="large"] #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon { + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"), 0, 16, 16, 0) center no-repeat; background-size: 12px; } #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { - background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 16, 32, 32, 16); + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } /*** Event notification ***/ #downloads-indicator-notification { opacity: 0; background: url("chrome://browser/skin/downloads/download-notification.png") center no-repeat;
--- a/browser/themes/gnomestripe/jar.mn +++ b/browser/themes/gnomestripe/jar.mn @@ -43,16 +43,17 @@ browser.jar: skin/classic/browser/click-to-play-warning-stripes.png skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar-small.png skin/classic/browser/urlbar-arrow.png skin/classic/browser/webRTC-shareDevice-16.png skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) + skin/classic/browser/downloads/download-glow-small.png (downloads/download-glow-small.png) skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png) skin/classic/browser/downloads/downloads.css (downloads/downloads.css) skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png) skin/classic/browser/feeds/videoFeedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16.png) skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
index 8babe61f450c5a27c8a37ab04687b6aa3eb4ab61..54216081c78c8a719bbec7459ef4b8167f9ac57e GIT binary patch literal 570 zc%17D@N?(olHy`uVBq!ia0vp^LLkh+3?vf;>QaG}WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8{{cQBu0WdAy6`^{VAA^2tB>AWdHC*<1GkqRyuD!W&4qh! z&f9&XYvu7dyRJ{)er@uWD?CmWJkAwt_7!Xnm7*EDMKX5t=A079JI#}GTBzWRXyIA@ zyt5*y+XVB^3m2UiPTj#;^MS4A1E*Ifr&kwO{b#QFFWi3p+^zrkqnGnHe&%obBGCR% zp#8r{K#xe-b&-}YBCTIU%WsHw{S)o_FBaS{UjJOO;J8%neW{M`(g};DbM{I1{+CHy zDwnrUp<tiFg#XI<yOj%et4;o|Gxfhg>rI2UTZS|K8+AP}oBiKv&R^@f|M^%0c!5En zRTAVE%)rPfAt@~@C$FfinwQ@@anh72)2GjzHEZtt{l_joeEaU(_a8rg{QUXr*Kh7S zr|N;aW_!9ghDb<GJ$O{8DS(0XLUzO5yLV+9I-4}ME&B6+`;QWt=Q|4?S{{%WYSQ2; zykI8oYrWpV`cCQJeeAi_%G(yK40mGnwG`yaIIX<#$ZW-{uf8pnRs6d9tO`f+4zt)3 z*-mjir}Atpldhi3@jG+u=mb&yZyBj4KH8XTu;^B7cJ-PYw|?&D%|AA<ed?{ccDmuv kFQd$U$#{wBms{q`@fb-=(TQC&1?Wr$Pgg&ebxsLQ01f31vH$=8
new file mode 100644 index 0000000000000000000000000000000000000000..054e4d1fad4f5f6dac69707664008d159b7c3145 GIT binary patch literal 1165 zc$@)^1akX{P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000D3Nkl<Zc-rmQ zTTI(k0LSr`LLqC}7!3Hg+?p|`GfW~71_OmaG@vm$6J<EvG&(Ud+R}}2b3nNXn7NB% zK%6?~gRe@KIOoC!(zxLaBe1dQs4%Qtx(XXXSod##o_`^Pf70~8EQJRizJ2JqeUhGD zQUQP!o$Y~T*_GHTaK!+Hj`B)S3LLbgz$jAm0*i7rF!Ifkud>&r9vqRT6hNA4KW>c7 z8Rh13Yg`G8-jH5m2+TN%pxvhtyyuMFxG`>yU)mu9x5lMFCbQvTL`f&2YW0Y!>$e{n z<L1aS8zx){6q2G9A2uVt@n0l<X(hpaWGt@!KEkuVpL97eTzvrvr>sc$0uGCBdVtO9 zb2gwS0r6T&;6`-|;!c5DY?B$AR6n{Ns35@D&p|Dw(TwnA0jgRM(*$Z!C(YQXTn1pM zvIS2!f?8y~8H$`4pm@7dz;6kG!8t96Yyh>bC(H=jw+z6beJzNn2el`Un-P+|3_uwH zZaD#JPaHENcoyhEK)jp;6xu18A;8U_f!bq7&5+Lm?d|obz{ef^I_d5kN?_E#Ap98U z9eIc#Rhtb+DP*BQ(WvQO?E2Ka9&u8>MVwp!eua?ks0UMc6N;mtcZ3CVup5$>kI$~> z=b4nxGU-K^IOIZs!l~&8G3(N_ebQGO;hpg{ymy|N*EjHe|2*W{VT67PdWWr$l^U>q z?>TNgzl_t6yi$+Am&$c?Ais!jFWz{M$vSJ?aG(bPMSmioxPPv|vSG+;rxA1*^axO1 zGljs?A>JMVMSA${??On{cly?@fednH7zN1BVzIo?+;JyMuIU&Fs2B%RX9e>KoKu|z z{#p|h`*r%Oe;9X@vyvD6E(YL17QT4)>fm0PrsHov?HK%P$;Nf~f7P<^D>ETXqq}`g zZ+eTIkqSUW13E&cpTA~!m&v{ImrvOkd}}Q5t;M5N!@{TZE<!cBTi5T5?IL@p%;6|N zM@V<FQQD=R;dhwa%Y$o6{((=m1wJ2RaaFTe`;id}O?z+8fDM<-!%=~B<ny}Tk+;d` zU%&K_3Eou}cvoX#Rk4s18xg8*zkbUw{s!4A34oj1c8y?hKsxfd%fB1<FlwECO|c1* zN(&@aa9kyeHASNY*VdySzMo0<c!t9X2~HU2<nLktBJNUmlFJ>a(%tqfx(lxg7G9OG zUpWiULJs$H*TCq+PO>&}9?r=?J~D;7M>19WO^-q&!~`O)06#4YkAe||sarc|aS1cH zTn^?0ARU?9J2<{erfk3AUSNbf0lAlBrZN_yd=A(4o53{sI++^>Kq!p2;hY4dBi+cs z&-RgfCC_Q?7Uc~=R5Cr&0Rt4Oiyg*$Q?HRZ+c=zn-~<H3%PBxQGO?e$giq!D^n*v% zuan{ru1v(_Uud4i#m?cjDedGGARTG7TDKC+j`@-2woq`c0dfEiLJA;lB88Lu={Q@f fe_*ZxS3K}P+f2UjENuW*00000NkvXXu0mjf=ousw
--- a/browser/themes/pinstripe/downloads/downloads.css +++ b/browser/themes/pinstripe/downloads/downloads.css @@ -170,42 +170,50 @@ richlistitem[type="download"][state="1"] #downloads-indicator-icon { background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 140, 20, 120) center no-repeat; } #downloads-indicator[attention] #downloads-indicator-icon { - background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 14, 34, 34, 14) center no-repeat; + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } #downloads-indicator:not([counter]) #downloads-indicator-counter { background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 140, 20, 120) center no-repeat; background-size: 12px; } #downloads-indicator:not([counter])[attention] #downloads-indicator-counter { - background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 14, 34, 34, 14); + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } @media (min-resolution: 2dppx) { #downloads-indicator-icon:not(:-moz-lwtheme-brighttext) { background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar@2x.png"), 0, 280, 40, 240); background-size: 20px; } #downloads-indicator:not([counter]) #downloads-indicator-counter { background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar@2x.png"), 0, 280, 40, 240); } + + #downloads-indicator[attention] + #downloads-indicator-icon { + background-image: url("chrome://browser/skin/downloads/download-glow@2x.png"); + } + + #downloads-indicator:not([counter])[attention] + #downloads-indicator-counter { + background-image: url("chrome://browser/skin/downloads/download-glow@2x.png"); + } } /*** Event notification ***/ #downloads-indicator-notification { opacity: 0; background: url("chrome://browser/skin/downloads/download-notification.png") center no-repeat;
--- a/browser/themes/pinstripe/jar.mn +++ b/browser/themes/pinstripe/jar.mn @@ -66,16 +66,17 @@ browser.jar: skin/classic/browser/urlbar-arrow.png skin/classic/browser/urlbar-arrow@2x.png skin/classic/browser/urlbar-popup-blocked.png skin/classic/browser/urlbar-popup-blocked@2x.png skin/classic/browser/webRTC-shareDevice-16.png skin/classic/browser/webRTC-shareDevice-64.png skin/classic/browser/downloads/buttons.png (downloads/buttons.png) skin/classic/browser/downloads/download-glow.png (downloads/download-glow.png) + skin/classic/browser/downloads/download-glow@2x.png (downloads/download-glow@2x.png) skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png) skin/classic/browser/downloads/downloads.css (downloads/downloads.css) skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css) skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css) skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png) skin/classic/browser/feeds/videoFeedIcon.png (feeds/feedIcon.png) skin/classic/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16.png)
deleted file mode 100644 index c70b5b0370796782dc0cf99b0a3f87ee9256e490..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
index c8b3dc02ff1a1bb3c053996039fae83ac3eed6a6..53182d7a407316db4ad925641c44d5d1b35d194e GIT binary patch literal 546 zc$@(u0^R+IP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B0005$Nkl<Zc-pm& zO-~b16o&821*IUA=}du!Dc>-33W47wAGVU<4t2qbkg$P(H1;EH2!=>0X$fcy3lahg zK&`c)2rm5rx`YCY!?~A)n;Qt&7#B}+=6%n3<`VMQ^-ll*=Rb@3kU@QijMM;mS<7KF zW}Ddkt%ysAGVTFor5Tj9mMbzik9nA^2vGn<ArsVH3)DRhpOsk?uq#3oG>H1z1p3L6 zU>SC|i<CasO`aNrM!Zm(?UY~{cGB*>qLN4hJk0qdFe^@^4jJUZd=ohGwgk(tyF)af zD{4^xMPJkc9j$}XDHF=p+oAlxmcWd4e1|@-0X3lSUyIa!oej#w#&oPA+H&Fe&<5q( z7F6VHc=X*bff?@{@7tg<+<G>>6`hns>Ju(&pWTVgIa3|ym026A4!fZ0hXl`9rzNdI z;`2fjZyIIMfKF(@U_op6<6J^ZS?A82AF7YKq57D^XXh6`xRSoYd@dQr-G-|hAri76 zFPanCg_xe|Jk#=c__Ld%ef5K}<U4(vPls^FixPGtMED^Pvc@;~SNF27pyA6je2II> zK1qFBeT7{;4RVPrqWB>pWZuR7bjXbN{PD(ne`gNg&0yxiPVC()60&;a88VF2(Eyhe kDMHv`$&i~PB)5w$0hfopsI#dlSpWb407*qoM6N<$g1XiG=>Px#
--- a/browser/themes/winstripe/downloads/downloads.css +++ b/browser/themes/winstripe/downloads/downloads.css @@ -176,29 +176,27 @@ richlistitem[type="download"][state="1"] } #downloads-indicator-icon:-moz-lwtheme-brighttext { background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 108, 18, 90) center no-repeat; } #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon { - background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 15, 33, 33, 15) center no-repeat; + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), 0, 108, 18, 90) center no-repeat; background-size: 12px; } #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter { - background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), - 16, 32, 32, 16); + background-image: url("chrome://browser/skin/downloads/download-glow.png"); } /*** Event notification ***/ #downloads-indicator-notification { opacity: 0; background: url("chrome://browser/skin/downloads/download-notification.png") center no-repeat;
--- a/browser/themes/winstripe/jar.mn +++ b/browser/themes/winstripe/jar.mn @@ -264,17 +264,17 @@ browser.jar: skin/classic/aero/browser/urlbar-arrow.png skin/classic/aero/browser/urlbar-popup-blocked.png skin/classic/aero/browser/urlbar-history-dropmarker.png skin/classic/aero/browser/webapps-16.png skin/classic/aero/browser/webapps-64.png skin/classic/aero/browser/webRTC-shareDevice-16.png skin/classic/aero/browser/webRTC-shareDevice-64.png skin/classic/aero/browser/downloads/buttons.png (downloads/buttons-aero.png) - skin/classic/aero/browser/downloads/download-glow.png (downloads/download-glow-aero.png) + skin/classic/aero/browser/downloads/download-glow.png (downloads/download-glow.png) skin/classic/aero/browser/downloads/download-notification.png (downloads/download-notification.png) * skin/classic/aero/browser/downloads/downloads.css (downloads/downloads-aero.css) skin/classic/aero/browser/feeds/feedIcon.png (feeds/feedIcon-aero.png) skin/classic/aero/browser/feeds/feedIcon16.png (feeds/feedIcon16-aero.png) skin/classic/aero/browser/feeds/audioFeedIcon.png (feeds/feedIcon-aero.png) skin/classic/aero/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16-aero.png) skin/classic/aero/browser/feeds/videoFeedIcon.png (feeds/feedIcon-aero.png) skin/classic/aero/browser/feeds/videoFeedIcon16.png (feeds/feedIcon16-aero.png)
--- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -36,17 +36,16 @@ nsCaseTreatment.h \ nsContentCID.h \ nsCopySupport.h \ nsContentCreatorFunctions.h \ nsDOMFile.h \ nsLineBreaker.h \ nsReferencedElement.h \ nsTreeSanitizer.h \ nsXMLNameSpaceMap.h \ -nsIXFormsUtilityService.h \ nsHostObjectProtocolHandler.h \ $(NULL) EXPORTS_NAMESPACES = mozilla/dom mozilla EXPORTS_mozilla/dom = \ DirectionalityUtils.h \ Element.h \
--- a/content/base/public/nsIDOMDataChannel.idl +++ b/content/base/public/nsIDOMDataChannel.idl @@ -1,15 +1,15 @@ #include "domstubs.idl" #include "nsIDOMEventTarget.idl" interface nsIVariant; -[scriptable, builtinclass, uuid(fb7a8ec4-c1eb-4d9f-b927-fbb8b4493e6d)] +[scriptable, builtinclass, uuid(7363aa5c-f4b2-4b86-8d15-e0f714c9216b)] interface nsIDOMDataChannel : nsIDOMEventTarget { readonly attribute DOMString label; readonly attribute boolean reliable; readonly attribute boolean ordered; readonly attribute DOMString readyState; readonly attribute unsigned long bufferedAmount; @@ -26,10 +26,10 @@ interface nsIDOMDataChannel : nsIDOMEven /** * Transmits data to other end of the connection. * @param data The data to be transmitted. Arraybuffers and Blobs are sent as * binary data. Strings are sent as UTF-8 text data. Other types are * converted to a String and sent as a String. * @return if the connection is still established and the data was queued or * sent successfully. */ - [implicit_jscontext] void send(in nsIVariant data); + void send(in nsIVariant data); };
deleted file mode 100644 --- a/content/base/public/nsIXFormsUtilityService.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsIXFormsUtilityService_h -#define nsIXFormsUtilityService_h - -#include "nsISupports.h" - -class nsIDOMNode; -class nsIDOMNodeList; -class nsIEditor; - -/* For IDL files that don't want to include root IDL files. */ -#ifndef NS_NO_VTABLE -#define NS_NO_VTABLE -#endif - -/* nsIXFormsUtilityService */ -#define NS_IXFORMSUTILITYSERVICE_IID_STR "cd3457b6-cb6a-496c-bdfa-6cfecb2bd5fb" -#define NS_IXFORMSUTILITYSERVICE_IID \ -{ 0xcd3457b6, 0xcb6a, 0x496c, \ - { 0xbd, 0xfa, 0x6c, 0xfe, 0xcb, 0x2b, 0xd5, 0xfb } } - - -/** - * Private interface implemented by the nsXFormsUtilityService in XForms - * extension. - */ -class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports { -public: - - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXFORMSUTILITYSERVICE_IID) - - enum { - STATE_OUT_OF_RANGE, - STATE_IN_RANGE, - STATE_NOT_A_RANGE - }; - - /** - * Returns the name of the builtin type of the instance node that aElement is - * bound to. Fails if aElement doesn't have a bound node. - */ - NS_IMETHOD GetBuiltinTypeName(nsIDOMNode *aElement, nsAString& aName) = 0; - - /** - * Return true if instance node that element is bound to is readonly. - */ - NS_IMETHOD IsReadonly(nsIDOMNode *aElement, bool *aState) = 0; - - /** - * Return true if instance node that element is bound to is relevant. - */ - NS_IMETHOD IsRelevant(nsIDOMNode *aElement, bool *aState) = 0; - - /** - * Return true if instance node that element is bound to is required. - */ - NS_IMETHOD IsRequired(nsIDOMNode *aElement, bool *aState) = 0; - - /** - * Return true if instance node that element is bound to is valid. - */ - NS_IMETHOD IsValid(nsIDOMNode *aElement, bool *aState) = 0; - - /** - * Return constant declared above that indicates whether instance node that - * element is bound to is out of range, is in range or neither. The last value - * is used if element can't have in-range or out-of-range state, for exmple, - * xforms:input. - */ - NS_IMETHOD IsInRange(nsIDOMNode *aElement, uint32_t *aState) = 0; - - /** - * Return value of instance node that given node is bound to. If given node is - * xforms:item element then the method returns item value. - */ - NS_IMETHOD GetValue(nsIDOMNode *aElement, nsAString& aValue) = 0; - - /** - * Set the focus to xforms element. - */ - NS_IMETHOD Focus(nsIDOMNode *aElement) = 0; - - /** - * Return @start attribute value of xforms:range element. Failure if - * given element is not xforms:range. - */ - NS_IMETHOD GetRangeStart(nsIDOMNode *aElement, nsAString& aValue) = 0; - - /** - * Return @end attribute value of xforms:range element. Failure if - * given element is not xforms:range. - */ - NS_IMETHOD GetRangeEnd(nsIDOMNode *aElement, nsAString& aValue) = 0; - - /** - * Return @step attribute value of xforms:range element. Failure if - * given element is not xforms:range. - */ - NS_IMETHOD GetRangeStep(nsIDOMNode *aElement, nsAString& aValue) = 0; - - /** - * Return nsIEditor for xforms element if element is editable, null if it is - * not editable. Failure if given element doesn't support editing. - */ - NS_IMETHOD GetEditor(nsIDOMNode *aElement, nsIEditor **aEditor) = 0; - - /** - * Return true if dropmarker is in open state (combobox popup is open), - * otherwise false. Failure if given 'aElement' node is not direct child of - * combobox element or is not combobox itself. - */ - NS_IMETHOD IsDropmarkerOpen(nsIDOMNode *aElement, bool* aIsOpen) = 0; - - /** - * Toggles dropmarker state (close/open combobox popup). Failure if given - * 'aElement' node is not direct child of combobox element or is not combobox - * itself. - */ - NS_IMETHOD ToggleDropmarkerState(nsIDOMNode *aElement) = 0; - - /** - * Get selected xforms:item element for xforms:select1. Failure if - * given 'aElement' node is not xforms:select1. - */ - NS_IMETHOD GetSelectedItemForSelect1(nsIDOMNode *aElement, - nsIDOMNode ** aItem) = 0; - - /** - * Set selected xforms:item element for xforms:select1. Failure if - * given 'aElement' node is not xforms:select1. - */ - NS_IMETHOD SetSelectedItemForSelect1(nsIDOMNode *aElement, - nsIDOMNode *aItem) = 0; - - /** - * Get the list of selected xforms:item elements from the xforms:select. - * Failure if given 'aElement' node is not xforms:select. - */ - NS_IMETHOD GetSelectedItemsForSelect(nsIDOMNode *aElement, - nsIDOMNodeList **aItems) = 0; - - /** - * Add xforms:item element to selection of xforms:select. Failure if - * given 'aElement' node is not xforms:select. - */ - NS_IMETHOD AddItemToSelectionForSelect(nsIDOMNode *aElement, - nsIDOMNode *Item) = 0; - - /** - * Remove xforms:item element from selection of xforms:select. Failure if - * given 'aElement' node is not xforms:select. - */ - NS_IMETHOD RemoveItemFromSelectionForSelect(nsIDOMNode *aElement, - nsIDOMNode *Item) = 0; - - /** - * Deslect all xforms:item elements contained in the given xforms:select. - * Failure if given 'aElement' node is not xforms:select. - */ - NS_IMETHOD ClearSelectionForSelect(nsIDOMNode *aElement) = 0; - - /** - * Select all xforms:item elements of xforms:select. Failure if - * given 'aElement' node is not xforms:select. - */ - NS_IMETHOD SelectAllItemsForSelect(nsIDOMNode *aElement) = 0; - - /** - * Return true if given xforms:item element of xforms:select is selected, - * otherwise return false. Failure if given 'aElement' node is not - * xforms:select. - */ - NS_IMETHOD IsSelectItemSelected(nsIDOMNode *aElement, nsIDOMNode *aItem, - bool *aIsSelected) = 0; - - /** - * Return the list of xforms:item or xforms:choices elements that are children - * of the given 'aElement' node. 'aElement' node may be a xforms:select, - * xforms:select1, xforms:choices or xforms:itemset element. Otherwise - * failure. - */ - NS_IMETHOD GetSelectChildrenFor(nsIDOMNode *aElement, - nsIDOMNodeList **aNodeList) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIXFormsUtilityService, - NS_IXFORMSUTILITYSERVICE_IID) - -#endif /* nsIXFormsUtilityService_h */
--- a/content/base/src/nsDOMBlobBuilder.cpp +++ b/content/base/src/nsDOMBlobBuilder.cpp @@ -235,17 +235,17 @@ nsDOMMultipartFile::InitInternal(JSConte continue; } if (JS_IsArrayBufferViewObject(&obj)) { blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj), JS_GetArrayBufferViewByteLength(&obj)); continue; } if (JS_IsArrayBufferObject(&obj)) { - blobSet.AppendArrayBuffer(&obj, aCx); + blobSet.AppendArrayBuffer(&obj); continue; } // neither Blob nor ArrayBuffer(View) } else if (element.isString()) { blobSet.AppendString(element.toString(), nativeEOL, aCx); continue; } // coerce it to a string @@ -314,13 +314,13 @@ BlobSet::AppendBlobs(const nsTArray<nsCO { Flush(); mBlobs.AppendElements(aBlob); return NS_OK; } nsresult -BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx) +BlobSet::AppendArrayBuffer(JSObject* aBuffer) { return AppendVoidPtr(JS_GetArrayBufferData(aBuffer), JS_GetArrayBufferByteLength(aBuffer)); }
--- a/content/base/src/nsDOMBlobBuilder.h +++ b/content/base/src/nsDOMBlobBuilder.h @@ -83,17 +83,17 @@ class BlobSet { public: BlobSet() : mData(nullptr), mDataLen(0), mDataBufferLen(0) {} nsresult AppendVoidPtr(const void* aData, uint32_t aLength); nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx); nsresult AppendBlob(nsIDOMBlob* aBlob); - nsresult AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx); + nsresult AppendArrayBuffer(JSObject* aBuffer); nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob); nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; } already_AddRefed<nsIDOMBlob> GetBlobInternal(const nsACString& aContentType) { nsCOMPtr<nsIDOMBlob> blob =
--- a/content/base/src/nsDOMDataChannel.cpp +++ b/content/base/src/nsDOMDataChannel.cpp @@ -83,18 +83,17 @@ public: virtual void AppReady(); private: // Get msg info out of JS variable being sent (string, arraybuffer, blob) nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut, nsCOMPtr<nsIInputStream> &aStreamOut, - bool &aIsBinary, uint32_t &aOutgoingLength, - JSContext *aCx); + bool &aIsBinary, uint32_t &aOutgoingLength); // Owning reference nsRefPtr<mozilla::DataChannel> mDataChannel; nsString mOrigin; enum { DC_BINARY_TYPE_ARRAYBUFFER, DC_BINARY_TYPE_BLOB, @@ -246,32 +245,32 @@ NS_IMETHODIMP nsDOMDataChannel::Close() { mDataChannel->Close(); return NS_OK; } // Almost a clone of nsWebSocketChannel::Send() NS_IMETHODIMP -nsDOMDataChannel::Send(nsIVariant* aData, JSContext* aCx) +nsDOMDataChannel::Send(nsIVariant* aData) { MOZ_ASSERT(NS_IsMainThread()); uint16_t state = mDataChannel->GetReadyState(); // In reality, the DataChannel protocol allows this, but we want it to // look like WebSockets if (state == mozilla::DataChannel::CONNECTING) { return NS_ERROR_DOM_INVALID_STATE_ERR; } nsCString msgString; nsCOMPtr<nsIInputStream> msgStream; bool isBinary; uint32_t msgLen; - nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen, aCx); + nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen); NS_ENSURE_SUCCESS(rv, rv); if (state == mozilla::DataChannel::CLOSING || state == mozilla::DataChannel::CLOSED) { return NS_OK; } MOZ_ASSERT(state == mozilla::DataChannel::OPEN, @@ -289,18 +288,17 @@ nsDOMDataChannel::Send(nsIVariant* aData } return sent >= 0 ? NS_OK : NS_ERROR_FAILURE; } // XXX Exact clone of nsWebSocketChannel::GetSendParams() - find a way to share! nsresult nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut, nsCOMPtr<nsIInputStream>& aStreamOut, - bool& aIsBinary, uint32_t& aOutgoingLength, - JSContext* aCx) + bool& aIsBinary, uint32_t& aOutgoingLength) { // Get type of data (arraybuffer, blob, or string) uint16_t dataType; nsresult rv = aData->GetDataType(&dataType); NS_ENSURE_SUCCESS(rv, rv); if (dataType == nsIDataType::VTYPE_INTERFACE || dataType == nsIDataType::VTYPE_INTERFACE_IS) {
--- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -2645,34 +2645,20 @@ GetRequestBody(nsIVariant* aBody, nsIInp // nsIXHRSendable? nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports); if (sendable) { return GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset); } // ArrayBuffer? jsval realVal; - nsCxPusher pusher; - Maybe<JSAutoCompartment> ac; - - // If there's a context on the stack, we can just use it. Otherwise, we need - // to use the safe js context (and push it into the stack, so that it's - // visible to cx-less functions that we might call here). - JSContext* cx = nsContentUtils::GetCurrentJSContext(); - if (!cx) { - cx = nsContentUtils::GetSafeJSContext(); - if (!pusher.Push(cx)) { - return NS_ERROR_FAILURE; - } - } nsresult rv = aBody->GetAsJSVal(&realVal); if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) { JSObject *obj = JSVAL_TO_OBJECT(realVal); - ac.construct(cx, obj); if (JS_IsArrayBufferObject(obj)) { ArrayBuffer buf(obj); return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset); } } } else if (dataType == nsIDataType::VTYPE_VOID || dataType == nsIDataType::VTYPE_EMPTY) {
--- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -3586,35 +3586,33 @@ CanvasRenderingContext2D::FillRuleChange { if (mPath) { mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule); mPath = nullptr; } } void -CanvasRenderingContext2D::PutImageData(JSContext* cx, - ImageData& imageData, double dx, +CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx, double dy, ErrorResult& error) { if (!FloatValidate(dx, dy)) { error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return; } dom::Uint8ClampedArray arr(imageData.GetDataObject()); error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy), imageData.Width(), imageData.Height(), arr.Data(), arr.Length(), false, 0, 0, 0, 0); } void -CanvasRenderingContext2D::PutImageData(JSContext* cx, - ImageData& imageData, double dx, +CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, ErrorResult& error) { if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) { error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return;
--- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -290,19 +290,19 @@ public: CreateImageData(JSContext* cx, double sw, double sh, mozilla::ErrorResult& error); already_AddRefed<mozilla::dom::ImageData> CreateImageData(JSContext* cx, mozilla::dom::ImageData& imagedata, mozilla::ErrorResult& error); already_AddRefed<mozilla::dom::ImageData> GetImageData(JSContext* cx, double sx, double sy, double sw, double sh, mozilla::ErrorResult& error); - void PutImageData(JSContext* cx, mozilla::dom::ImageData& imageData, + void PutImageData(mozilla::dom::ImageData& imageData, double dx, double dy, mozilla::ErrorResult& error); - void PutImageData(JSContext* cx, mozilla::dom::ImageData& imageData, + void PutImageData(mozilla::dom::ImageData& imageData, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight, mozilla::ErrorResult& error); double LineWidth() { return CurrentState().lineWidth; }
--- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -837,28 +837,28 @@ public: void StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask); void StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask); void StencilMask(WebGLuint mask); void StencilMaskSeparate(WebGLenum face, WebGLuint mask); void StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass); void StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass); - void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level, + void TexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLsizei width, WebGLsizei height, WebGLint border, WebGLenum format, WebGLenum type, dom::ArrayBufferView *pixels, ErrorResult& rv); - void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level, + void TexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLenum format, WebGLenum type, dom::ImageData* pixels, ErrorResult& rv); // Allow whatever element types the bindings are willing to pass // us in TexImage2D template<class ElementType> - void TexImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level, + void TexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLenum format, WebGLenum type, ElementType* elt, ErrorResult& rv) { if (!IsContextStable()) return; nsRefPtr<gfxImageSurface> isurf; WebGLTexelFormat srcFormat; nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt); rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf), @@ -874,28 +874,28 @@ public: } void TexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) { TexParameter_base(target, pname, nullptr, ¶m); } void TexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) { TexParameter_base(target, pname, ¶m, nullptr); } - void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level, + void TexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLsizei width, WebGLsizei height, WebGLenum format, WebGLenum type, dom::ArrayBufferView* pixels, ErrorResult& rv); - void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level, + void TexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLenum format, WebGLenum type, dom::ImageData* pixels, ErrorResult& rv); // Allow whatever element types the bindings are willing to pass // us in TexSubImage2D template<class ElementType> - void TexSubImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level, + void TexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLenum format, WebGLenum type, ElementType* elt, ErrorResult& rv) { if (!IsContextStable()) return; nsRefPtr<gfxImageSurface> isurf; WebGLTexelFormat srcFormat; nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt); rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
--- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -4857,33 +4857,33 @@ WebGLContext::TexImage2D_base(WebGLenum GenerateWarning("texImage2D generated error %s", ErrorName(error)); return; } tex->SetImageInfo(target, level, width, height, format, type); } void -WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level, +WebGLContext::TexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLsizei width, WebGLsizei height, WebGLint border, WebGLenum format, WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv) { if (!IsContextStable()) return; return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type, pixels ? pixels->Data() : 0, pixels ? pixels->Length() : 0, pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1, WebGLTexelConversions::Auto, false); } void -WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level, +WebGLContext::TexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLenum format, WebGLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) return; if (!pixels) { // Spec says to generate an INVALID_VALUE error @@ -5006,17 +5006,17 @@ WebGLContext::TexSubImage2D_base(WebGLen actualSrcFormat, srcPremultiplied, dstFormat, mPixelStorePremultiplyAlpha, dstTexelSize); gl->fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, convertedData); } } void -WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level, +WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLsizei width, WebGLsizei height, WebGLenum format, WebGLenum type, ArrayBufferView* pixels, ErrorResult& rv) { if (!IsContextStable()) return; @@ -5027,17 +5027,17 @@ WebGLContext::TexSubImage2D(JSContext* c return TexSubImage2D_base(target, level, xoffset, yoffset, width, height, 0, format, type, pixels->Data(), pixels->Length(), JS_GetTypedArrayType(pixels->Obj()), WebGLTexelConversions::Auto, false); } void -WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level, +WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLenum format, WebGLenum type, ImageData* pixels, ErrorResult& rv) { if (!IsContextStable()) return; if (!pixels)
--- a/content/svg/content/src/nsSVGElement.cpp +++ b/content/svg/content/src/nsSVGElement.cpp @@ -1102,25 +1102,16 @@ private: MappedAttrParser::MappedAttrParser(css::Loader* aLoader, nsIURI* aDocURI, already_AddRefed<nsIURI> aBaseURI, nsIPrincipal* aNodePrincipal) : mParser(aLoader), mDocURI(aDocURI), mBaseURI(aBaseURI), mNodePrincipal(aNodePrincipal), mDecl(nullptr) { - // SVG and CSS differ slightly in their interpretation of some of - // the attributes. SVG allows attributes of the form: font-size="5" - // (style="font-size: 5" if using a style attribute) - // where CSS requires units: font-size="5pt" (style="font-size: 5pt") - // Set a flag to pass information to the parser so that we can use - // the CSS parser to parse the font-size attribute. Note that this - // does *not* affect the use of CSS stylesheets, which will still - // require units. - mParser.SetSVGMode(true); } MappedAttrParser::~MappedAttrParser() { NS_ABORT_IF_FALSE(!mDecl, "If mDecl was initialized, it should have been converted " "into a style rule (and had its pointer cleared)"); } @@ -1136,17 +1127,17 @@ MappedAttrParser::ParseMappedAttrValue(n // Get the nsCSSProperty ID for our mapped attribute. nsCSSProperty propertyID = nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName), nsCSSProps::eEnabled); if (propertyID != eCSSProperty_UNKNOWN) { bool changed; // outparam for ParseProperty. (ignored) mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI, - mNodePrincipal, mDecl, &changed, false); + mNodePrincipal, mDecl, &changed, false, true); return; } NS_ABORT_IF_FALSE(aMappedAttrName == nsGkAtoms::lang, "Only 'lang' should be unrecognized!"); // nsCSSParser doesn't know about 'lang', so we need to handle it specially. if (aMappedAttrName == nsGkAtoms::lang) { propertyID = eCSSProperty__x_lang; nsCSSExpandedDataBlock block;
--- a/dom/activities/src/Activity.cpp +++ b/dom/activities/src/Activity.cpp @@ -1,16 +1,17 @@ /* 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 "Activity.h" #include "nsDOMClassInfo.h" #include "nsContentUtils.h" #include "nsIDOMActivityOptions.h" +#include "nsEventStateManager.h" using namespace mozilla::dom; #ifdef MOZ_SYS_MSG DOMCI_DATA(MozActivity, Activity) #endif NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Activity) @@ -46,16 +47,24 @@ Activity::Initialize(nsISupports* aOwner uint32_t aArgc, JS::Value* aArgv) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner); NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED); Init(window); + if (!nsEventStateManager::IsHandlingUserInput()) { + nsCOMPtr<nsIDOMRequestService> rs = + do_GetService("@mozilla.org/dom/dom-request-service;1"); + rs->FireErrorAsync(static_cast<DOMRequest*>(this), + NS_LITERAL_STRING("NotUserInput")); + return NS_OK; + } + // We expect a single argument, which is a nsIDOMMozActivityOptions. if (aArgc != 1 || !aArgv[0].isObject()) { return NS_ERROR_INVALID_ARG; } nsCOMPtr<nsISupports> tmp; nsContentUtils::XPConnect()->WrapJS(aContext, aArgv[0].toObjectOrNull(), NS_GET_IID(nsIDOMMozActivityOptions),
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -123,17 +123,17 @@ DOMInterfaces = { 'headerFile': 'nsIDOMFile.h', }, { 'workers': True, }], 'CanvasRenderingContext2D': { 'implicitJSContext': [ - 'createImageData', 'getImageData', 'putImageData', 'strokeStyle', + 'createImageData', 'getImageData', 'strokeStyle', 'fillStyle', 'mozDash' ], 'resultNotAddRefed': [ 'canvas' ], 'binaryNames': { 'mozImageSmoothingEnabled': 'imageSmoothingEnabled', 'mozFillRule': 'fillRule' } }, @@ -444,17 +444,17 @@ DOMInterfaces = { 'headerFile': 'WebGLContext.h' }, 'WebGLRenderingContext': { 'nativeType': 'mozilla::WebGLContext', 'headerFile': 'WebGLContext.h', 'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension', 'getAttachedShaders' ], - 'implicitJSContext': [ 'texImage2D', 'texSubImage2D', 'getSupportedExtensions' ], + 'implicitJSContext': [ 'getSupportedExtensions' ], }, 'WebGLShader': { 'nativeType': 'mozilla::WebGLShader', 'headerFile': 'WebGLContext.h' }, 'WebGLShaderPrecisionFormat': {
new file mode 100644 --- /dev/null +++ b/dom/media/tests/crashtests/801227.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html class="reftest-wait"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=801227 +--> +<head> + <meta charset="utf-8"> + <title>Abort due to page reload</title> + <script type="application/javascript"> + var pc = new mozRTCPeerConnection(); + + var index = localStorage.index || 0; + if (index < 3) { + localStorage.index = index + 1; + window.location.reload(); + } + + function finish() { + delete localStorage["index"]; + + pc.close(); + document.documentElement.removeAttribute("class"); + } + + navigator.mozGetUserMedia({ audio: true, fake: true }, function (aStream) { + pc.addStream(aStream); + finish(); + }, finish); + </script> +</head> + +<body> +</body> +</html> +
--- a/dom/media/tests/crashtests/crashtests.list +++ b/dom/media/tests/crashtests/crashtests.list @@ -1,4 +1,5 @@ pref(media.peerconnection.enabled,true) load 780790.html pref(media.peerconnection.enabled,true) load 791270.html pref(media.peerconnection.enabled,true) load 791278.html pref(media.peerconnection.enabled,true) load 791330.html +pref(media.peerconnection.enabled,true) load 801227.html
--- a/dom/system/OSFileConstants.cpp +++ b/dom/system/OSFileConstants.cpp @@ -402,16 +402,21 @@ static dom::ConstantSpec gLibcProperties { "OSFILE_OFFSETOF_STAT_ST_MTIME", INT_TO_JSVAL(offsetof (struct stat, st_mtimespec)) }, { "OSFILE_OFFSETOF_STAT_ST_CTIME", INT_TO_JSVAL(offsetof (struct stat, st_ctimespec)) }, #else { "OSFILE_OFFSETOF_STAT_ST_ATIME", INT_TO_JSVAL(offsetof (struct stat, st_atime)) }, { "OSFILE_OFFSETOF_STAT_ST_MTIME", INT_TO_JSVAL(offsetof (struct stat, st_mtime)) }, { "OSFILE_OFFSETOF_STAT_ST_CTIME", INT_TO_JSVAL(offsetof (struct stat, st_ctime)) }, #endif // defined(HAVE_ST_ATIME) + // Several OSes have a birthtime field. For the moment, supporting only Darwin. +#if defined(_DARWIN_FEATURE_64_BIT_INODE) + { "OSFILE_OFFSETOF_STAT_ST_BIRTHTIME", INT_TO_JSVAL(offsetof (struct stat, st_birthtime)) }, +#endif // defined(_DARWIN_FEATURE_64_BIT_INODE) + #endif // defined(XP_UNIX) // System configuration // Under MacOSX, to avoid using deprecated functions that do not // match the constants we define in this object (including
--- a/dom/telephony/CallEvent.cpp +++ b/dom/telephony/CallEvent.cpp @@ -21,31 +21,19 @@ CallEvent::Create(TelephonyCall* aCall) nsRefPtr<CallEvent> event = new CallEvent(); event->mCall = aCall; return event.forget(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(CallEvent) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CallEvent, - nsDOMEvent) - // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mCall->ToISupports(), - // TelephonyCall, "mCall") - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCall"); - cb.NoteNativeChild(tmp->mCall->ToISupports(), NS_CYCLE_COLLECTION_PARTICIPANT(TelephonyCall)); - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CallEvent, - nsDOMEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mCall) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_INHERITED_1(CallEvent, + nsDOMEvent, + mCall) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CallEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMCallEvent) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CallEvent) NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent) NS_IMPL_ADDREF_INHERITED(CallEvent, nsDOMEvent) NS_IMPL_RELEASE_INHERITED(CallEvent, nsDOMEvent)
--- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -135,30 +135,19 @@ TelephonyCall::NotifyError(const nsAStri NS_ASSERTION(event, "This should never fail!"); if (NS_FAILED(event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("error")))) { NS_WARNING("Failed to dispatch error event!"); } } -NS_IMPL_CYCLE_COLLECTION_CLASS(TelephonyCall) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCall, - nsDOMEventTargetHelper) - // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mTelephony->ToISupports(), - // Telephony, "mTelephony") - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mTelephony"); - cb.NoteNativeChild(tmp->mTelephony->ToISupports(), NS_CYCLE_COLLECTION_PARTICIPANT(Telephony)); -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCall, - nsDOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mTelephony) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_INHERITED_1(TelephonyCall, + nsDOMEventTargetHelper, + mTelephony) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall) NS_INTERFACE_MAP_ENTRY(nsIDOMTelephonyCall) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TelephonyCall) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(TelephonyCall, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(TelephonyCall, nsDOMEventTargetHelper)
--- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -206,17 +206,17 @@ public: static const gfx::Rect CalculatePendingDisplayPort( const FrameMetrics& aFrameMetrics, const gfx::Point& aVelocity, const gfx::Point& aAcceleration, double aEstimatedPaintDuration); /** * Return the scale factor needed to fit the viewport in |aMetrics| - * into its compositiong bounds. + * into its composition bounds. */ static gfxSize CalculateIntrinsicScale(const FrameMetrics& aMetrics); /** * Return the resolution that content should be rendered at given * the configuration in aFrameMetrics: viewport dimensions, zoom * factor, etc. (The mResolution member of aFrameMetrics is * ignored.)
--- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -25,17 +25,17 @@ using mozilla::DebugOnly; namespace js { namespace ion { StringObject * MNewStringObject::templateObj() const { return &templateObj_->asString(); } -CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph &graph) +CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph *graph) : CodeGeneratorSpecific(gen, graph) { } bool CodeGenerator::visitValueToInt32(LValueToInt32 *lir) { ValueOperand operand = ToValue(lir, LValueToInt32::Input); @@ -2978,49 +2978,50 @@ CodeGenerator::visitGetArgument(LGetArgu masm.loadValue(argPtr, result); } return true; } bool CodeGenerator::generate() { - AssertCanGC(); - JSContext *cx = GetIonContext()->cx; - - unsigned slots = graph.localSlotCount() + - (graph.argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE); - if (!safepoints_.init(slots)) + if (!safepoints_.init(graph.totalSlotCount())) return false; // Before generating any code, we generate type checks for all parameters. // This comes before deoptTable_, because we can't use deopt tables without // creating the actual frame. if (!generateArgumentsChecks()) return false; if (frameClass_ != FrameSizeClass::None()) { - deoptTable_ = cx->compartment->ionCompartment()->getBailoutTable(frameClass_); + deoptTable_ = GetIonContext()->compartment->ionCompartment()->getBailoutTable(frameClass_); if (!deoptTable_) return false; } if (!generatePrologue()) return false; if (!generateBody()) return false; if (!generateEpilogue()) return false; if (!generateInvalidateEpilogue()) return false; if (!generateOutOfLineCode()) return false; - if (masm.oom()) - return false; + return !masm.oom(); +} + +bool +CodeGenerator::link() +{ + AssertCanGC(); + JSContext *cx = GetIonContext()->cx; Linker linker(masm); IonCode *code = linker.newCode(cx); if (!code) return false; // We encode safepoints after the OSI-point offsets have been determined. encodeSafepoints(); @@ -3034,17 +3035,17 @@ CodeGenerator::generate() : FrameSizeClass::FromDepth(frameDepth_).frameSize(); // Check to make sure we didn't have a mid-build invalidation. If so, we // will trickle to ion::Compile() and return Method_Skipped. if (cx->compartment->types.compiledInfo.compilerOutput(cx)->isInvalidated()) return true; IonScript *ionScript = - IonScript::New(cx, slots, scriptFrameSize, snapshots_.size(), + IonScript::New(cx, graph.totalSlotCount(), scriptFrameSize, snapshots_.size(), bailouts_.length(), graph.numConstants(), safepointIndices_.length(), osiIndices_.length(), cacheList_.length(), barrierOffsets_.length(), safepoints_.size(), graph.mir().numScripts()); SetIonScript(script, executionMode, ionScript); if (!ionScript) return false;
--- a/js/src/ion/CodeGenerator.h +++ b/js/src/ion/CodeGenerator.h @@ -31,20 +31,21 @@ class OutOfLineTypeOfV; class OutOfLineLoadTypedArray; class CodeGenerator : public CodeGeneratorSpecific { bool generateArgumentsChecks(); bool generateBody(); public: - CodeGenerator(MIRGenerator *gen, LIRGraph &graph); + CodeGenerator(MIRGenerator *gen, LIRGraph *graph); public: bool generate(); + bool link(); bool visitLabel(LLabel *lir); bool visitNop(LNop *lir); bool visitOsiPoint(LOsiPoint *lir); bool visitGoto(LGoto *lir); bool visitTableSwitch(LTableSwitch *ins); bool visitTableSwitchV(LTableSwitchV *ins); bool visitParameter(LParameter *lir);
--- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -202,21 +202,28 @@ IonCompartment::IonCompartment(IonRuntim : rt(rt), flusher_(NULL) { } void ion::FinishOffThreadBuilder(IonBuilder *builder) { + // Clean up if compilation did not succeed. if (builder->script()->isIonCompilingOffThread()) { types::TypeCompartment &types = builder->script()->compartment()->types; builder->recompileInfo.compilerOutput(types)->invalidate(); builder->script()->ion = NULL; } + + // The builder is allocated into its LifoAlloc, so destroying that will + // destroy the builder and all other data accumulated during compilation, + // except any final codegen (which includes an assembler and needs to be + // explicitly destroyed). + js_delete(builder->backgroundCodegen()); js_delete(builder->temp().lifoAlloc()); } static inline void FinishAllOffThreadCompilations(IonCompartment *ion) { OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations(); @@ -755,17 +762,17 @@ ion::ToggleBarriers(JSCompartment *comp, if (script->hasIonScript()) script->ion->toggleBarriers(needs); } } namespace js { namespace ion { -LIRGraph * +CodeGenerator * CompileBackEnd(MIRGenerator *mir) { IonSpewPass("BuildSSA"); // Note: don't call AssertGraphCoherency before SplitCriticalEdges, // the graph is not in RPO at this point. MIRGraph &graph = mir->graph(); @@ -941,17 +948,23 @@ CompileBackEnd(MIRGenerator *mir) if (!regalloc.go()) return NULL; IonSpewPass("Allocate Registers", ®alloc); if (mir->shouldCancel("Allocate Registers")) return NULL; } - return lir; + CodeGenerator *codegen = js_new<CodeGenerator>(mir, lir); + if (!codegen || !codegen->generate()) { + js_delete(codegen); + return NULL; + } + + return codegen; } class AutoDestroyAllocator { LifoAlloc *alloc; public: AutoDestroyAllocator(LifoAlloc *alloc) : alloc(alloc) {} @@ -992,34 +1005,37 @@ AttachFinishedCompilations(JSContext *cx OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations(); // Incorporate any off thread compilations which have finished, failed or // have been cancelled, and destroy JM jitcode for any compilations which // succeeded, to allow entering the Ion code from the interpreter. while (!compilations.empty()) { IonBuilder *builder = compilations.popCopy(); - if (builder->backgroundCompiledLir) { + if (CodeGenerator *codegen = builder->backgroundCodegen()) { RootedScript script(cx, builder->script()); IonContext ictx(cx, cx->compartment, &builder->temp()); - CodeGenerator codegen(builder, *builder->backgroundCompiledLir); + // Root the assembler until the builder is finished below. As it + // was constructed off thread, the assembler has not been rooted + // previously, though any GC activity would discard the builder. + codegen->masm.constructRoot(cx); types::AutoEnterTypeInference enterTypes(cx); ExecutionMode executionMode = builder->info().executionMode(); types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode)); enterCompiler.initExisting(builder->recompileInfo); bool success; { // Release the worker thread lock and root the compiler for GC. AutoTempAllocatorRooter root(cx, &builder->temp()); AutoUnlockWorkerThreadState unlock(cx->runtime); - success = codegen.generate(); + success = codegen->link(); } if (success) { if (script->hasIonScript()) mjit::ReleaseScriptCodeFromVM(cx, script); } else { // Silently ignore OOM during code generation, we're at an // operation callback and can't propagate failures. @@ -1118,31 +1134,28 @@ SequentialCompileContext::compile(IonBui // The allocator and associated data will be destroyed after being // processed in the finishedOffThreadCompilations list. autoDestroy.cancel(); return true; } - LIRGraph *lir = CompileBackEnd(builder); - if (!lir) { + CodeGenerator *codegen = CompileBackEnd(builder); + if (!codegen) { IonSpew(IonSpew_Abort, "Failed during back-end compilation."); return false; } - CodeGenerator codegen(builder, *lir); - if (!codegen.generate()) { - IonSpew(IonSpew_Abort, "Failed during code generation."); - return false; - } + bool success = codegen->link(); + js_delete(codegen); IonSpewEndFunction(); - return true; + return success; } bool TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing) { SequentialCompileContext compileContext; if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) { if (!cx->isExceptionPending())
--- a/js/src/ion/Ion.h +++ b/js/src/ion/Ion.h @@ -248,19 +248,19 @@ void Invalidate(JSContext *cx, const Vec bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true); void MarkFromIon(JSCompartment *comp, Value *vp); void ToggleBarriers(JSCompartment *comp, bool needs); class IonBuilder; class MIRGenerator; -class LIRGraph; +class CodeGenerator; -LIRGraph *CompileBackEnd(MIRGenerator *mir); +CodeGenerator *CompileBackEnd(MIRGenerator *mir); void AttachFinishedCompilations(JSContext *cx); void FinishOffThreadBuilder(IonBuilder *builder); bool TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing); static inline bool IsEnabled(JSContext *cx) { return cx->hasRunOption(JSOPTION_ION) && cx->typeInferenceEnabled(); }
--- a/js/src/ion/IonBuilder.cpp +++ b/js/src/ion/IonBuilder.cpp @@ -25,17 +25,17 @@ using namespace js; using namespace js::ion; using mozilla::DebugOnly; IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph, TypeOracle *oracle, CompileInfo *info, size_t inliningDepth, uint32 loopDepth) : MIRGenerator(cx->compartment, temp, graph, info), recompileInfo(cx->compartment->types.compiledInfo), - backgroundCompiledLir(NULL), + backgroundCodegen_(NULL), cx(cx), loopDepth_(loopDepth), callerResumePoint_(NULL), callerBuilder_(NULL), oracle(oracle), inliningDepth(inliningDepth), failedBoundsCheck_(info->script()->failedBoundsCheck), failedShapeGuard_(info->script()->failedShapeGuard),
--- a/js/src/ion/IonBuilder.h +++ b/js/src/ion/IonBuilder.h @@ -12,17 +12,17 @@ // JSScript. #include "MIR.h" #include "MIRGraph.h" namespace js { namespace ion { -class LIRGraph; +class CodeGenerator; class IonBuilder : public MIRGenerator { enum ControlStatus { ControlStatus_Error, ControlStatus_Ended, // There is no continuation/join point. ControlStatus_Joined, // Created a join node. ControlStatus_Jumped, // Parsing another branch at the same level. @@ -434,27 +434,32 @@ class IonBuilder : public MIRGenerator MGetPropertyCache *getPropCache, types::StackTypeSet *types, types::StackTypeSet *barrier, MBasicBlock *bottom, Vector<MDefinition *, 8, IonAllocPolicy> &retvalDefns); // A builder is inextricably tied to a particular script. HeapPtrScript script_; + // If off thread compilation is successful, the final code generator is + // attached here. Code has been generated, but not linked (there is not yet + // an IonScript). This is heap allocated, and must be explicitly destroyed. + CodeGenerator *backgroundCodegen_; + public: // Compilation index for this attempt. types::RecompileInfo const recompileInfo; - // If off thread compilation is successful, final LIR is attached here. - LIRGraph *backgroundCompiledLir; - void clearForBackEnd(); Return<JSScript*> script() const { return script_; } + CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; } + void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; } + private: JSContext *cx; jsbytecode *pc; MBasicBlock *current; uint32 loopDepth_; /* Information used for inline-call builders. */
--- a/js/src/ion/IonMacroAssembler.h +++ b/js/src/ion/IonMacroAssembler.h @@ -46,17 +46,17 @@ class MacroAssembler : public MacroAssem masm_(masm) { } MacroAssembler *masm() const { return masm_; } }; - AutoRooter autoRooter_; + mozilla::Maybe<AutoRooter> autoRooter_; mozilla::Maybe<IonContext> ionContext_; mozilla::Maybe<AutoIonContextAlloc> alloc_; bool enoughMemory_; private: // This field is used to manage profiling instrumentation output. If // provided and enabled, then instrumentation will be emitted around call // sites. The IonInstrumentation instance is hosted inside of @@ -64,41 +64,48 @@ class MacroAssembler : public MacroAssem // actually emitted or not. If NULL, then no instrumentation is emitted. IonInstrumentation *sps_; public: // If instrumentation should be emitted, then the sps parameter should be // provided, but otherwise it can be safely omitted to prevent all // instrumentation from being emitted. MacroAssembler(IonInstrumentation *sps = NULL) - : autoRooter_(GetIonContext()->cx, thisFromCtor()), - enoughMemory_(true), + : enoughMemory_(true), sps_(sps) { + JSContext *cx = GetIonContext()->cx; + if (cx) + constructRoot(cx); + if (!GetIonContext()->temp) - alloc_.construct(GetIonContext()->cx); + alloc_.construct(cx); #ifdef JS_CPU_ARM m_buffer.id = GetIonContext()->getNextAssemblerId(); #endif } // This constructor should only be used when there is no IonContext active // (for example, Trampoline-$(ARCH).cpp). MacroAssembler(JSContext *cx) - : autoRooter_(cx, thisFromCtor()), - enoughMemory_(true), + : enoughMemory_(true), sps_(NULL) // no need for instrumentation in trampolines and such { + constructRoot(cx); ionContext_.construct(cx, cx->compartment, (js::ion::TempAllocator *)NULL); alloc_.construct(cx); #ifdef JS_CPU_ARM m_buffer.id = GetIonContext()->getNextAssemblerId(); #endif } + void constructRoot(JSContext *cx) { + autoRooter_.construct(cx, this); + } + MoveResolver &moveResolver() { return moveResolver_; } size_t instructionsSize() const { return size(); } @@ -150,21 +157,21 @@ class MacroAssembler : public MacroAssem } void loadStringLength(Register str, Register dest) { loadPtr(Address(str, JSString::offsetOfLengthAndFlags()), dest); rshiftPtr(Imm32(JSString::LENGTH_SHIFT), dest); } void loadJSContext(const Register &dest) { - movePtr(ImmWord(GetIonContext()->cx->runtime), dest); + movePtr(ImmWord(GetIonContext()->compartment->rt), dest); loadPtr(Address(dest, offsetof(JSRuntime, ionJSContext)), dest); } void loadIonActivation(const Register &dest) { - movePtr(ImmWord(GetIonContext()->cx->runtime), dest); + movePtr(ImmWord(GetIonContext()->compartment->rt), dest); loadPtr(Address(dest, offsetof(JSRuntime, ionActivation)), dest); } template<typename T> void loadTypedOrValue(const T &src, TypedOrValueRegister dest) { if (dest.hasValue()) loadValue(src, dest.valueReg()); else @@ -365,17 +372,17 @@ class MacroAssembler : public MacroAssem if (key.isRegister()) branch32(cond, length, key.reg(), label); else branch32(cond, length, Imm32(key.constant()), label); } void branchTestNeedsBarrier(Condition cond, const Register &scratch, Label *label) { JS_ASSERT(cond == Zero || cond == NonZero); - JSCompartment *comp = GetIonContext()->cx->compartment; + JSCompartment *comp = GetIonContext()->compartment; movePtr(ImmWord(comp), scratch); Address needsBarrierAddr(scratch, JSCompartment::OffsetOfNeedsBarrier()); branchTest32(cond, needsBarrierAddr, Imm32(0x1), label); } template <typename T> void callPreBarrier(const T &address, MIRType type) { JS_ASSERT(type == MIRType_Value || type == MIRType_String || type == MIRType_Object);
--- a/js/src/ion/LIR.h +++ b/js/src/ion/LIR.h @@ -1139,16 +1139,19 @@ class LIRGraph return localSlotCount_; } void setArgumentSlotCount(uint32 argumentSlotCount) { argumentSlotCount_ = argumentSlotCount; } uint32 argumentSlotCount() const { return argumentSlotCount_; } + uint32 totalSlotCount() const { + return localSlotCount() + (argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE); + } bool addConstantToPool(const Value &v, uint32 *index); size_t numConstants() const { return constantPool_.length(); } HeapValue *constantPool() { return &constantPool_[0]; } const HeapValue &getConstant(size_t index) const {
--- a/js/src/ion/arm/CodeGenerator-arm.cpp +++ b/js/src/ion/arm/CodeGenerator-arm.cpp @@ -46,17 +46,17 @@ class DeferredJumpTable : public Deferre *jumpData = (void *)(code->raw() + masm->actualOffset(offset)); jumpData++; } } }; // shared -CodeGeneratorARM::CodeGeneratorARM(MIRGenerator *gen, LIRGraph &graph) +CodeGeneratorARM::CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph) : CodeGeneratorShared(gen, graph), deoptLabel_(NULL) { } bool CodeGeneratorARM::generatePrologue() {
--- a/js/src/ion/arm/CodeGenerator-arm.h +++ b/js/src/ion/arm/CodeGenerator-arm.h @@ -117,17 +117,17 @@ class CodeGeneratorARM : public CodeGene void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType, const Register &elements, const LAllocation *index); protected: void linkAbsoluteLabels(); public: - CodeGeneratorARM(MIRGenerator *gen, LIRGraph &graph); + CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph); public: bool visitBox(LBox *box); bool visitBoxDouble(LBoxDouble *box); bool visitUnbox(LUnbox *unbox); bool visitValue(LValue *value); bool visitOsrValue(LOsrValue *value); bool visitDouble(LDouble *ins);
--- a/js/src/ion/shared/CodeGenerator-shared.cpp +++ b/js/src/ion/shared/CodeGenerator-shared.cpp @@ -16,31 +16,31 @@ using namespace js; using namespace js::ion; using mozilla::DebugOnly; namespace js { namespace ion { -CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph &graph) +CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph) : oolIns(NULL), masm(&sps_), gen(gen), - graph(graph), + graph(*graph), current(NULL), deoptTable_(NULL), #ifdef DEBUG pushedArgs_(0), #endif lastOsiPointOffset_(0), sps_(&gen->compartment->rt->spsProfiler, &lastPC_), osrEntryOffset_(0), - frameDepth_(graph.localSlotCount() * sizeof(STACK_SLOT_SIZE) + - graph.argumentSlotCount() * sizeof(Value)) + frameDepth_(graph->localSlotCount() * sizeof(STACK_SLOT_SIZE) + + graph->argumentSlotCount() * sizeof(Value)) { frameClass_ = FrameSizeClass::FromDepth(frameDepth_); } bool CodeGeneratorShared::generateOutOfLineCode() { for (size_t i = 0; i < outOfLineCode_.length(); i++) {
--- a/js/src/ion/shared/CodeGenerator-shared.h +++ b/js/src/ion/shared/CodeGenerator-shared.h @@ -30,18 +30,20 @@ template <class ArgSeq, class StoreOutpu class OutOfLineCallVM; class OutOfLineTruncateSlow; class CodeGeneratorShared : public LInstructionVisitor { js::Vector<OutOfLineCode *, 0, SystemAllocPolicy> outOfLineCode_; OutOfLineCode *oolIns; + public: + MacroAssembler masm; + protected: - MacroAssembler masm; MIRGenerator *gen; LIRGraph &graph; LBlock *current; SnapshotWriter snapshots_; IonCode *deoptTable_; #ifdef DEBUG uint32 pushedArgs_; #endif @@ -277,17 +279,17 @@ class CodeGeneratorShared : public LInst void linkAbsoluteLabels() { } private: void generateInvalidateEpilogue(); public: - CodeGeneratorShared(MIRGenerator *gen, LIRGraph &graph); + CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph); public: template <class ArgSeq, class StoreOutputTo> bool visitOutOfLineCallVM(OutOfLineCallVM<ArgSeq, StoreOutputTo> *ool); bool visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool); };
--- a/js/src/ion/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/ion/shared/CodeGenerator-x86-shared.cpp @@ -39,17 +39,17 @@ class DeferredJumpTable : public Deferre uint32 offset = caseheader->offset(); *jumpData = (void *)(code->raw() + offset); jumpData++; } } }; -CodeGeneratorX86Shared::CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph &graph) +CodeGeneratorX86Shared::CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph) : CodeGeneratorShared(gen, graph), deoptLabel_(NULL) { } double test(double x, double y) {
--- a/js/src/ion/shared/CodeGenerator-x86-shared.h +++ b/js/src/ion/shared/CodeGenerator-x86-shared.h @@ -78,17 +78,17 @@ class CodeGeneratorX86Shared : public Co // true, and the false block if |cond| is false. void emitBranch(Assembler::Condition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse, NaNCond ifNaN = NaN_Unexpected); void emitBranch(Assembler::DoubleCondition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse); bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base); public: - CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph &graph); + CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph); public: // Instruction visitors. virtual bool visitMinMaxD(LMinMaxD *ins); virtual bool visitNegD(LNegD *ins); virtual bool visitAbsD(LAbsD *ins); virtual bool visitSqrtD(LSqrtD *ins); virtual bool visitPowHalfD(LPowHalfD *ins);
--- a/js/src/ion/x64/CodeGenerator-x64.cpp +++ b/js/src/ion/x64/CodeGenerator-x64.cpp @@ -11,17 +11,17 @@ #include "ion/MIRGraph.h" #include "jsnum.h" #include "jsscope.h" #include "jsscopeinlines.h" using namespace js; using namespace js::ion; -CodeGeneratorX64::CodeGeneratorX64(MIRGenerator *gen, LIRGraph &graph) +CodeGeneratorX64::CodeGeneratorX64(MIRGenerator *gen, LIRGraph *graph) : CodeGeneratorX86Shared(gen, graph) { } ValueOperand CodeGeneratorX64::ToValue(LInstruction *ins, size_t pos) { return ValueOperand(ToRegister(ins->getOperand(pos)));
--- a/js/src/ion/x64/CodeGenerator-x64.h +++ b/js/src/ion/x64/CodeGenerator-x64.h @@ -29,17 +29,17 @@ class CodeGeneratorX64 : public CodeGene void loadUnboxedValue(Operand source, MIRType type, const LDefinition *dest); void storeUnboxedValue(const LAllocation *value, MIRType valueType, Operand dest, MIRType slotType); void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType, const Register &elements, const LAllocation *index); public: - CodeGeneratorX64(MIRGenerator *gen, LIRGraph &graph); + CodeGeneratorX64(MIRGenerator *gen, LIRGraph *graph); public: bool visitValue(LValue *value); bool visitOsrValue(LOsrValue *value); bool visitBox(LBox *box); bool visitUnbox(LUnbox *unbox); bool visitDouble(LDouble *ins); bool visitLoadSlotV(LLoadSlotV *ins);
--- a/js/src/ion/x86/CodeGenerator-x86.cpp +++ b/js/src/ion/x86/CodeGenerator-x86.cpp @@ -13,17 +13,17 @@ #include "jsscope.h" #include "jsscriptinlines.h" using namespace js; using namespace js::ion; using mozilla::DebugOnly; -CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph &graph) +CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph) : CodeGeneratorX86Shared(gen, graph) { } static const uint32 FrameSizes[] = { 128, 256, 512, 1024 }; FrameSizeClass FrameSizeClass::FromDepth(uint32 frameDepth)
--- a/js/src/ion/x86/CodeGenerator-x86.h +++ b/js/src/ion/x86/CodeGenerator-x86.h @@ -47,17 +47,17 @@ class CodeGeneratorX86 : public CodeGene void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType, const Register &elements, const LAllocation *index); protected: void linkAbsoluteLabels(); public: - CodeGeneratorX86(MIRGenerator *gen, LIRGraph &graph); + CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph); public: bool visitBox(LBox *box); bool visitBoxDouble(LBoxDouble *box); bool visitUnbox(LUnbox *unbox); bool visitValue(LValue *value); bool visitOsrValue(LOsrValue *value); bool visitDouble(LDouble *ins);
--- a/js/src/jsworkers.cpp +++ b/js/src/jsworkers.cpp @@ -278,16 +278,19 @@ WorkerThread::ThreadMain(void *arg) } void WorkerThread::threadLoop() { WorkerThreadState &state = *runtime->workerThreadState; state.lock(); + threadData.construct(runtime); + js::TlsPerThreadData.set(threadData.addr()); + while (true) { JS_ASSERT(!ionBuilder); while (state.ionWorklist.empty()) { if (terminate) { state.unlock(); return; } @@ -298,17 +301,17 @@ WorkerThread::threadLoop() ion::ExecutionMode executionMode = ionBuilder->info().executionMode(); JS_ASSERT(GetIonScript(ionBuilder->script().unsafeGet(), executionMode) == ION_COMPILING_SCRIPT); state.unlock(); { ion::IonContext ictx(NULL, ionBuilder->script()->compartment(), &ionBuilder->temp()); - ionBuilder->backgroundCompiledLir = ion::CompileBackEnd(ionBuilder); + ionBuilder->setBackgroundCodegen(ion::CompileBackEnd(ionBuilder)); } state.lock(); FinishOffThreadIonCompile(ionBuilder); ionBuilder = NULL; /*
--- a/js/src/jsworkers.h +++ b/js/src/jsworkers.h @@ -77,16 +77,18 @@ class WorkerThreadState /* Condvar to notify helper threads that they may be able to make progress. */ PRCondVar *helperWakeup; }; /* Individual helper thread, one allocated per core. */ struct WorkerThread { JSRuntime *runtime; + + mozilla::Maybe<PerThreadData> threadData; PRThread *thread; /* Indicate to an idle thread that it should finish executing. */ bool terminate; /* Any builder currently being compiled by Ion on this thread. */ ion::IonBuilder *ionBuilder;
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -1108,27 +1108,28 @@ nsXPCWrappedJSClass::CheckForException(X return pending_result; } } return NS_ERROR_FAILURE; } NS_IMETHODIMP nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex, - const XPTMethodDescriptor* info, + const XPTMethodDescriptor* info_, nsXPTCMiniVariant* nativeParams) { jsval* sp = nullptr; jsval* argv = nullptr; uint8_t i; nsresult retval = NS_ERROR_FAILURE; nsresult pending_result = NS_OK; JSBool success; JSBool readyToDoTheCall = false; nsID param_iid; + const nsXPTMethodInfo* info = static_cast<const nsXPTMethodInfo*>(info_); const char* name = info->name; jsval fval; JSBool foundDependentParam; // Make sure not to set the callee on ccx until after we've gone through // the whole nsIXPCFunctionThisTranslator bit. That code uses ccx to // convert natives to JSObjects, but we do NOT plan to pass those JSObjects // to our real callee. @@ -1138,16 +1139,27 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra return retval; XPCContext *xpcc = ccx.GetXPCContext(); JSContext *cx = xpc_UnmarkGrayContext(ccx.GetJSContext()); if (!cx || !xpcc || !IsReflectable(methodIndex)) return NS_ERROR_FAILURE; + // [implicit_jscontext] and [optional_argc] have a different calling + // convention, which we don't support for JS-implemented components. + if (info->WantsOptArgc() || info->WantsContext()) { + const char *str = "IDL methods marked with [implicit_jscontext] " + "or [optional_argc] may not be implemented in JS"; + // Throw and warn for good measure. + JS_ReportError(cx, str); + NS_WARNING(str); + return NS_ERROR_FAILURE; + } + JSObject *obj = wrapper->GetJSObject(); JSObject *thisObj = obj; JSAutoCompartment ac(cx, obj); ccx.SetScopeForNewJSObjects(obj); JS::AutoValueVector args(cx); AutoScriptEvaluate scriptEval(cx);
--- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -9,23 +9,23 @@ #include "nsAttrValue.h" #include "nsAutoCopyListener.h" #include "nsColorNames.h" #include "nsComputedDOMStyle.h" #include "nsContentDLF.h" #include "nsContentUtils.h" #include "nsCSSAnonBoxes.h" +#include "mozilla/css/ErrorReporter.h" #include "nsCSSKeywords.h" #include "nsCSSParser.h" #include "nsCSSProps.h" #include "nsCSSPseudoClasses.h" #include "nsCSSPseudoElements.h" #include "nsCSSRendering.h" -#include "nsCSSScanner.h" #include "nsDOMAttribute.h" #include "nsDOMClassInfo.h" #include "nsEventListenerManager.h" #include "nsFrame.h" #include "nsGlobalWindow.h" #include "nsGkAtoms.h" #include "nsImageFrame.h" #include "nsLayoutStylesheetCache.h" @@ -307,17 +307,17 @@ nsLayoutStatics::Shutdown() nsSprocketLayout::Shutdown(); #endif nsMathMLOperators::ReleaseTable(); nsFloatManager::Shutdown(); nsImageFrame::ReleaseGlobals(); - nsCSSScanner::ReleaseGlobals(); + mozilla::css::ErrorReporter::ReleaseGlobals(); nsTextFragment::Shutdown(); nsAttrValue::Shutdown(); nsContentUtils::Shutdown(); nsNodeInfo::ClearCache(); nsLayoutStylesheetCache::Shutdown(); NS_NameSpaceManagerShutdown();
deleted file mode 100644 --- a/layout/reftests/svg/inline-in-xul-basic-01.xul +++ /dev/null @@ -1,12 +0,0 @@ -<!-- - Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ ---> - -<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=364732 --> - -<box xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1"> - <svg xmlns="http://www.w3.org/2000/svg"> - <rect fill="lime" width="100%" height="100%"/> - </svg> -</box>
--- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -157,17 +157,16 @@ fails-if(Android) == filter-extref-diffe == foreignObject-dynamic-abspos-01.html foreignObject-dynamic-abspos-01-ref.html == foreignObject-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html == foreignObject-dynamic-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html == getElementById-a-element-01.svg pass.svg fuzzy-if(Android,9,980) == gradient-live-01a.svg gradient-live-01-ref.svg fuzzy-if(Android,9,980) == gradient-live-01b.svg gradient-live-01-ref.svg fuzzy-if(Android,9,980) == gradient-live-01c.svg gradient-live-01-ref.svg fuzzy-if(Android,9,980) == gradient-live-01d.svg gradient-live-01-ref.svg -fails == inline-in-xul-basic-01.xul pass.svg == invalid-text-01.svg pass.svg == lang-attribute-01.svg pass.svg == lang-attribute-02.svg pass.svg == lang-attribute-03.svg pass.svg == linearGradient-basic-01.svg pass.svg == linearGradient-basic-02.svg pass.svg == markers-and-group-opacity-01.svg markers-and-group-opacity-01-ref.svg == marker-attribute-01.svg pass.svg
new file mode 100644 --- /dev/null +++ b/layout/style/ErrorReporter.cpp @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/* diagnostic reporting for CSS style sheet parser */ + +#include "mozilla/css/ErrorReporter.h" +#include "mozilla/css/Loader.h" +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" +#include "nsCSSScanner.h" +#include "nsCSSStyleSheet.h" +#include "nsIConsoleService.h" +#include "nsIDocument.h" +#include "nsIFactory.h" +#include "nsIScriptError.h" +#include "nsIServiceManager.h" +#include "nsIStringBundle.h" +#include "nsThreadUtils.h" + +#ifdef CSS_REPORT_PARSE_ERRORS + +using mozilla::Preferences; +namespace services = mozilla::services; + +namespace { +class ShortTermURISpecCache : public nsRunnable { +public: + ShortTermURISpecCache() : mPending(false) {} + + nsString const& GetSpec(nsIURI* aURI) { + if (mURI != aURI) { + mURI = aURI; + + nsAutoCString cSpec; + mURI->GetSpec(cSpec); + CopyUTF8toUTF16(cSpec, mSpec); + } + return mSpec; + } + + bool IsInUse() const { return mURI != nullptr; } + bool IsPending() const { return mPending; } + void SetPending() { mPending = true; } + + // When invoked as a runnable, zap the cache. + NS_IMETHOD Run() { + mURI = nullptr; + mSpec.Truncate(); + mPending = false; + return NS_OK; + } + +private: + nsCOMPtr<nsIURI> mURI; + nsString mSpec; + bool mPending; +}; +} + +static bool sReportErrors; +static nsIConsoleService *sConsoleService; +static nsIFactory *sScriptErrorFactory; +static nsIStringBundle *sStringBundle; +static ShortTermURISpecCache *sSpecCache; + +#define CSS_ERRORS_PREF "layout.css.report_errors" + +static bool +InitGlobals() +{ + NS_ABORT_IF_FALSE(!sConsoleService && !sScriptErrorFactory && !sStringBundle, + "should not have been called"); + + if (NS_FAILED(Preferences::AddBoolVarCache(&sReportErrors, CSS_ERRORS_PREF, + true))) { + return false; + } + + nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (!cs) { + return false; + } + + nsCOMPtr<nsIFactory> sf = do_GetClassObject(NS_SCRIPTERROR_CONTRACTID); + if (!sf) { + return false; + } + + nsCOMPtr<nsIStringBundleService> sbs = services::GetStringBundleService(); + if (!sbs) { + return false; + } + + nsCOMPtr<nsIStringBundle> sb; + nsresult rv = sbs->CreateBundle("chrome://global/locale/css.properties", + getter_AddRefs(sb)); + if (NS_FAILED(rv) || !sb) { + return false; + } + + sConsoleService = cs.forget().get(); + sScriptErrorFactory = sf.forget().get(); + sStringBundle = sb.forget().get(); + + return true; +} + +static inline bool +ShouldReportErrors() +{ + if (!sConsoleService) { + if (!InitGlobals()) { + return false; + } + } + return sReportErrors; +} + +namespace mozilla { +namespace css { + +/* static */ void +ErrorReporter::ReleaseGlobals() +{ + NS_IF_RELEASE(sConsoleService); + NS_IF_RELEASE(sScriptErrorFactory); + NS_IF_RELEASE(sStringBundle); + NS_IF_RELEASE(sSpecCache); +} + +ErrorReporter::ErrorReporter(const nsCSSScanner& aScanner, + const nsCSSStyleSheet* aSheet, + const Loader* aLoader, + nsIURI* aURI) + : mScanner(&aScanner), mSheet(aSheet), mLoader(aLoader), mURI(aURI), + mInnerWindowID(0), mErrorLineNumber(0), mErrorColNumber(0) +{ +} + +ErrorReporter::~ErrorReporter() +{ + // Schedule deferred cleanup for cached data. We want to strike a + // balance between performance and memory usage, so we only allow + // short-term caching. + if (sSpecCache && sSpecCache->IsInUse() && !sSpecCache->IsPending()) { + if (NS_FAILED(NS_DispatchToCurrentThread(sSpecCache))) { + // Peform the "deferred" cleanup immediately if the dispatch fails. + sSpecCache->Run(); + } else { + sSpecCache->SetPending(); + } + } +} + +void +ErrorReporter::OutputError() +{ + if (mError.IsEmpty()) { + return; + } + if (!ShouldReportErrors()) { + ClearError(); + return; + } + + if (mInnerWindowID == 0 && (mSheet || mLoader)) { + if (mSheet) { + mInnerWindowID = mSheet->FindOwningWindowInnerID(); + } + if (mInnerWindowID == 0 && mLoader) { + nsIDocument* doc = mLoader->GetDocument(); + if (doc) { + mInnerWindowID = doc->InnerWindowID(); + } + } + // don't attempt this again, even if we failed + mSheet = nullptr; + mLoader = nullptr; + } + + if (mFileName.IsEmpty()) { + if (mURI) { + if (!sSpecCache) { + sSpecCache = new ShortTermURISpecCache; + NS_ADDREF(sSpecCache); + } + mFileName = sSpecCache->GetSpec(mURI); + mURI = nullptr; + } else { + mFileName.AssignLiteral("from DOM"); + } + } + + nsresult rv; + nsCOMPtr<nsIScriptError> errorObject = + do_CreateInstance(sScriptErrorFactory, &rv); + + if (NS_SUCCEEDED(rv)) { + rv = errorObject->InitWithWindowID(mError, + mFileName, + EmptyString(), + mErrorLineNumber, + mErrorColNumber, + nsIScriptError::warningFlag, + "CSS Parser", + mInnerWindowID); + if (NS_SUCCEEDED(rv)) { + sConsoleService->LogMessage(errorObject); + } + } + + ClearError(); +} + +void +ErrorReporter::ClearError() +{ + mError.Truncate(); +} + +void +ErrorReporter::AddToError(const nsString &aErrorText) +{ + if (!ShouldReportErrors()) return; + + if (mError.IsEmpty()) { + mErrorLineNumber = mScanner->GetLineNumber(); + mErrorColNumber = mScanner->GetColumnNumber(); + mError = aErrorText; + } else { + mError.AppendLiteral(" "); + mError.Append(aErrorText); + } +} + +void +ErrorReporter::ReportUnexpected(const char *aMessage) +{ + if (!ShouldReportErrors()) return; + + nsAutoString str; + sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), + getter_Copies(str)); + AddToError(str); +} + +void +ErrorReporter::ReportUnexpected(const char *aMessage, + const nsString &aParam) +{ + if (!ShouldReportErrors()) return; + + const PRUnichar *params[1] = { aParam.get() }; + nsAutoString str; + sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), + params, ArrayLength(params), + getter_Copies(str)); + AddToError(str); +} + +void +ErrorReporter::ReportUnexpected(const char *aMessage, + const nsCSSToken &aToken) +{ + if (!ShouldReportErrors()) return; + + nsAutoString tokenString; + aToken.AppendToString(tokenString); + const PRUnichar *params[1] = { tokenString.get() }; + + nsAutoString str; + sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), + params, ArrayLength(params), + getter_Copies(str)); + AddToError(str); +} + +void +ErrorReporter::ReportUnexpected(const char *aMessage, + const nsCSSToken &aToken, + PRUnichar aChar) +{ + if (!ShouldReportErrors()) return; + + nsAutoString tokenString; + aToken.AppendToString(tokenString); + const PRUnichar charStr[2] = { aChar, 0 }; + const PRUnichar *params[2] = { tokenString.get(), charStr }; + + nsAutoString str; + sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), + params, ArrayLength(params), + getter_Copies(str)); + AddToError(str); +} + +void +ErrorReporter::ReportUnexpectedEOF(const char *aMessage) +{ + if (!ShouldReportErrors()) return; + + nsAutoString innerStr; + sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), + getter_Copies(innerStr)); + const PRUnichar *params[1] = { innerStr.get() }; + + nsAutoString str; + sStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(), + params, ArrayLength(params), + getter_Copies(str)); + AddToError(str); +} + +void +ErrorReporter::ReportUnexpectedEOF(PRUnichar aExpected) +{ + if (!ShouldReportErrors()) return; + + const PRUnichar expectedStr[] = { + PRUnichar('\''), aExpected, PRUnichar('\''), PRUnichar(0) + }; + const PRUnichar *params[1] = { expectedStr }; + + nsAutoString str; + sStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(), + params, ArrayLength(params), + getter_Copies(str)); + AddToError(str); +} + +} // namespace css +} // namespace mozilla + +#endif
new file mode 100644 --- /dev/null +++ b/layout/style/ErrorReporter.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +/* diagnostic reporting for CSS style sheet parser */ + +#ifndef mozilla_css_ErrorReporter_h_ +#define mozilla_css_ErrorReporter_h_ + +// XXX turn this off for minimo builds +#define CSS_REPORT_PARSE_ERRORS + +#include "nsString.h" + +struct nsCSSToken; +class nsCSSStyleSheet; +class nsCSSScanner; +class nsIURI; + +namespace mozilla { +namespace css { + +class Loader; + +// If CSS_REPORT_PARSE_ERRORS is not defined, all of this class's +// methods become inline stubs. +class NS_STACK_CLASS ErrorReporter { +public: + ErrorReporter(const nsCSSScanner &aScanner, + const nsCSSStyleSheet *aSheet, + const Loader *aLoader, + nsIURI *aURI); + ~ErrorReporter(); + + static void ReleaseGlobals(); + + void OutputError(); + void ClearError(); + + // In all overloads of ReportUnexpected, aMessage is a stringbundle + // name, which will be processed as a format string with the + // indicated number of parameters. + + // no parameters + void ReportUnexpected(const char *aMessage); + // one parameter, a string + void ReportUnexpected(const char *aMessage, const nsString& aParam); + // one parameter, a token + void ReportUnexpected(const char *aMessage, const nsCSSToken& aToken); + // two parameters, a token and a character, in that order + void ReportUnexpected(const char *aMessage, const nsCSSToken& aToken, + PRUnichar aChar); + + // for ReportUnexpectedEOF, aExpected can be either a stringbundle + // name or a single character. In the former case there may not be + // any format parameters. + void ReportUnexpectedEOF(const char *aExpected); + void ReportUnexpectedEOF(PRUnichar aExpected); + +private: + void AddToError(const nsString &aErrorText); + +#ifdef CSS_REPORT_PARSE_ERRORS + nsAutoString mError; + nsString mFileName; + const nsCSSScanner *mScanner; + const nsCSSStyleSheet *mSheet; + const Loader *mLoader; + nsIURI *mURI; + uint64_t mInnerWindowID; + uint32_t mErrorLineNumber; + uint32_t mErrorColNumber; +#endif +}; + +#ifndef CSS_REPORT_PARSE_ERRORS +inline ErrorReporter::ErrorReporter(const nsCSSScanner&, + const nsCSSStyleSheet*, + const Loader*, + nsIURI*) {} +inline ErrorReporter::~ErrorReporter() {} + +inline void ErrorReporter::ReleaseGlobals() {} + +inline void ErrorReporter::OutputError() {} +inline void ErrorReporter::ClearError() {} + +inline void ErrorReporter::ReportUnexpected(const char *) {} +inline void ErrorReporter::ReportUnexpected(const char *, const nsString &) {} +inline void ErrorReporter::ReportUnexpected(const char *, const nsCSSToken &) {} +inline void ErrorReporter::ReportUnexpected(const char *, const nsCSSToken &, + PRUnichar) {} + +inline void ErrorReporter::ReportUnexpectedEOF(const char *) {} +inline void ErrorReporter::ReportUnexpectedEOF(PRUnichar) {} + +inline void ErrorReporter::AddToError(const nsString &) {} +#endif + +} // namespace css +} // namespace mozilla + +#endif // mozilla_css_ErrorReporter_h_
--- a/layout/style/Makefile.in +++ b/layout/style/Makefile.in @@ -66,30 +66,32 @@ EXPORTS = \ nsStyleStructInlines.h \ nsStyleStructList.h \ nsStyleTransformMatrix.h \ nsStyleUtil.h \ $(NULL) EXPORTS_mozilla/css = \ Declaration.h \ + ErrorReporter.h \ GroupRule.h \ ImageLoader.h \ ImportRule.h \ Loader.h \ NameSpaceRule.h \ Rule.h \ StyleRule.h \ $(NULL) CPPSRCS = \ AnimationCommon.cpp \ nsCSSAnonBoxes.cpp \ nsCSSDataBlock.cpp \ Declaration.cpp \ + ErrorReporter.cpp \ nsCSSKeywords.cpp \ ImageLoader.cpp \ Loader.cpp \ nsAnimationManager.cpp \ nsCSSParser.cpp \ nsCSSProps.cpp \ nsCSSPseudoClasses.cpp \ nsCSSPseudoElements.cpp \
--- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* parsing of CSS stylesheets, based on a token stream from the CSS scanner */ #include "nsCSSParser.h" #include "nsCSSProps.h" #include "nsCSSKeywords.h" #include "nsCSSScanner.h" +#include "mozilla/css/ErrorReporter.h" #include "mozilla/css/Loader.h" #include "mozilla/css/StyleRule.h" #include "mozilla/css/ImportRule.h" #include "nsCSSRules.h" #include "mozilla/css/NameSpaceRule.h" #include "nsTArray.h" #include "nsCSSStyleSheet.h" #include "mozilla/css/Declaration.h" @@ -156,18 +157,16 @@ class CSSParserImpl { public: CSSParserImpl(); ~CSSParserImpl(); nsresult SetStyleSheet(nsCSSStyleSheet* aSheet); nsresult SetQuirkMode(bool aQuirkMode); - nsresult SetSVGMode(bool aSVGMode); - nsresult SetChildLoader(mozilla::css::Loader* aChildLoader); // Clears everything set by the above Set*() functions. void Reset(); nsresult ParseSheet(const nsAString& aInput, nsIURI* aSheetURI, nsIURI* aBaseURI, @@ -196,17 +195,18 @@ public: nsresult ParseProperty(const nsCSSProperty aPropID, const nsAString& aPropValue, nsIURI* aSheetURL, nsIURI* aBaseURL, nsIPrincipal* aSheetPrincipal, css::Declaration* aDeclaration, bool* aChanged, - bool aIsImportant); + bool aIsImportant, + bool aIsSVGMode); nsresult ParseMediaList(const nsSubstring& aBuffer, nsIURI* aURL, // for error reporting uint32_t aLineNumber, // for error reporting nsMediaList* aMediaList, bool aHTMLMode); bool ParseColorString(const nsSubstring& aBuffer, @@ -254,41 +254,37 @@ protected: { mParser->SetParsingCompoundProperty(false); } private: CSSParserImpl* mParser; }; // the caller must hold on to aString until parsing is done - void InitScanner(const nsSubstring& aString, nsIURI* aSheetURI, - uint32_t aLineNumber, nsIURI* aBaseURI, + void InitScanner(nsCSSScanner& aScanner, + css::ErrorReporter& aReporter, + nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal); void ReleaseScanner(void); bool IsSVGMode() const { - return mScanner.IsSVGMode(); + return mScanner->IsSVGMode(); } bool GetToken(bool aSkipWS); void UngetToken(); // get the part in paretheses of the url() function, which is really a // part of a token in the CSS grammar, but we're using a combination // of the parser and the scanner to do it to handle the backtracking // required by the error handling of the tokenization (since if we // fail to scan the full token, we should fall back to tokenizing as // FUNCTION ... ')'). // Note that this function WILL WRITE TO aURL IN SOME FAILURE CASES. bool GetURLInParens(nsString& aURL); - void AssertInitialState() { - NS_PRECONDITION(!mHTMLMediaMode, "Bad initial state"); - NS_PRECONDITION(!mParsingCompoundProperty, "Bad initial state"); - } - bool ExpectSymbol(PRUnichar aSymbol, bool aSkipWS); bool ExpectEndProperty(); bool CheckEndProperty(); nsSubstring* NextIdent(); void SkipUntil(PRUnichar aStopSymbol); void SkipUntilOneOf(const PRUnichar* aStopSymbolChars); void SkipRuleSet(bool aInsideBraces); bool SkipAtRule(bool aInsideBlock); @@ -630,17 +626,20 @@ protected: /* Find the correct default namespace, and set it on aSelector. */ void SetDefaultNamespaceOnSelector(nsCSSSelector& aSelector); // Current token. The value is valid after calling GetToken and invalidated // by UngetToken. nsCSSToken mToken; // Our scanner. - nsCSSScanner mScanner; + nsCSSScanner* mScanner; + + // Our error reporter. + css::ErrorReporter* mReporter; // The URI to be used as a base for relative URIs. nsCOMPtr<nsIURI> mBaseURI; // The URI to be used as an HTTP "Referer" and for error reporting. nsCOMPtr<nsIURI> mSheetURI; // The principal of the sheet involved @@ -685,20 +684,16 @@ protected: // True for parsing media lists for HTML attributes, where we have to // ignore CSS comments. bool mHTMLMediaMode : 1; // This flag is set when parsing a non-box shorthand; it's used to not apply // some quirks during shorthand parsing bool mParsingCompoundProperty : 1; -#ifdef DEBUG - bool mScannerInited : 1; -#endif - // Stack of rule groups; used for @media and such. InfallibleTArray<nsRefPtr<css::GroupRule> > mGroupStack; // During the parsing of a property (which may be a shorthand), the data // are stored in |mTempData|. (It is needed to ensure that parser // errors cause the data to be ignored, and to ensure that a // non-'!important' declaration does not override an '!important' // one.) @@ -718,73 +713,54 @@ static void AppendRuleToArray(css::Rule* } static void AppendRuleToSheet(css::Rule* aRule, void* aParser) { CSSParserImpl* parser = (CSSParserImpl*) aParser; parser->AppendRule(aRule); } -#ifdef CSS_REPORT_PARSE_ERRORS - #define REPORT_UNEXPECTED(msg_) \ - mScanner.ReportUnexpected(#msg_) - -#define REPORT_UNEXPECTED_P(msg_, params_) \ - mScanner.ReportUnexpectedParams(#msg_, params_) - -#define REPORT_UNEXPECTED_EOF(lf_) \ - mScanner.ReportUnexpectedEOF(#lf_) - -#define REPORT_UNEXPECTED_EOF_CHAR(ch_) \ - mScanner.ReportUnexpectedEOF(ch_) + mReporter->ReportUnexpected(#msg_) + +#define REPORT_UNEXPECTED_P(msg_, param_) \ + mReporter->ReportUnexpected(#msg_, param_) #define REPORT_UNEXPECTED_TOKEN(msg_) \ - mScanner.ReportUnexpectedToken(mToken, #msg_) - -#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_) \ - mScanner.ReportUnexpectedTokenParams(mToken, #msg_, \ - params_, ArrayLength(params_)) - + mReporter->ReportUnexpected(#msg_, mToken) + +#define REPORT_UNEXPECTED_TOKEN_CHAR(msg_, ch_) \ + mReporter->ReportUnexpected(#msg_, mToken, ch_) + +#define REPORT_UNEXPECTED_EOF(lf_) \ + mReporter->ReportUnexpectedEOF(#lf_) + +#define REPORT_UNEXPECTED_EOF_CHAR(ch_) \ + mReporter->ReportUnexpectedEOF(ch_) #define OUTPUT_ERROR() \ - mScanner.OutputError() + mReporter->OutputError() #define CLEAR_ERROR() \ - mScanner.ClearError() - -#else - -#define REPORT_UNEXPECTED(msg_) -#define REPORT_UNEXPECTED_P(msg_, params_) -#define REPORT_UNEXPECTED_EOF(lf_) -#define REPORT_UNEXPECTED_EOF_CHAR(ch_) -#define REPORT_UNEXPECTED_TOKEN(msg_) -#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_) -#define OUTPUT_ERROR() -#define CLEAR_ERROR() - -#endif + mReporter->ClearError() CSSParserImpl::CSSParserImpl() : mToken(), - mScanner(), + mScanner(nullptr), + mReporter(nullptr), mChildLoader(nullptr), mSection(eCSSSection_Charset), mNameSpaceMap(nullptr), mHavePushBack(false), mNavQuirkMode(false), mHashlessColorQuirk(false), mUnitlessLengthQuirk(false), mUnsafeRulesEnabled(false), mHTMLMediaMode(false), mParsingCompoundProperty(false), -#ifdef DEBUG - mScannerInited(false), -#endif mNextFree(nullptr) { } CSSParserImpl::~CSSParserImpl() { mData.AssertInitialState(); mTempData.AssertInitialState(); @@ -812,101 +788,89 @@ CSSParserImpl::SetStyleSheet(nsCSSStyleS nsresult CSSParserImpl::SetQuirkMode(bool aQuirkMode) { mNavQuirkMode = aQuirkMode; return NS_OK; } nsresult -CSSParserImpl::SetSVGMode(bool aSVGMode) -{ - mScanner.SetSVGMode(aSVGMode); - return NS_OK; -} - -nsresult CSSParserImpl::SetChildLoader(mozilla::css::Loader* aChildLoader) { mChildLoader = aChildLoader; // not ref counted, it owns us return NS_OK; } void CSSParserImpl::Reset() { - NS_ASSERTION(! mScannerInited, "resetting with scanner active"); + NS_ASSERTION(!mScanner, "resetting with scanner active"); SetStyleSheet(nullptr); SetQuirkMode(false); - SetSVGMode(false); SetChildLoader(nullptr); } void -CSSParserImpl::InitScanner(const nsSubstring& aString, nsIURI* aSheetURI, - uint32_t aLineNumber, nsIURI* aBaseURI, +CSSParserImpl::InitScanner(nsCSSScanner& aScanner, + css::ErrorReporter& aReporter, + nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal) { - // Having it not own the string is OK since the caller will hold on to - // the stream until we're done parsing. - NS_ASSERTION(! mScannerInited, "already have scanner"); - - mScanner.Init(aString, aSheetURI, aLineNumber, mSheet, mChildLoader); - -#ifdef DEBUG - mScannerInited = true; -#endif + NS_PRECONDITION(!mHTMLMediaMode, "Bad initial state"); + NS_PRECONDITION(!mParsingCompoundProperty, "Bad initial state"); + NS_PRECONDITION(!mScanner, "already have scanner"); + + mScanner = &aScanner; + mReporter = &aReporter; + mScanner->SetErrorReporter(mReporter); + mBaseURI = aBaseURI; mSheetURI = aSheetURI; mSheetPrincipal = aSheetPrincipal; - mHavePushBack = false; } void -CSSParserImpl::ReleaseScanner(void) -{ - mScanner.Close(); -#ifdef DEBUG - mScannerInited = false; -#endif +CSSParserImpl::ReleaseScanner() +{ + mScanner = nullptr; + mReporter = nullptr; mBaseURI = nullptr; mSheetURI = nullptr; mSheetPrincipal = nullptr; } nsresult CSSParserImpl::ParseSheet(const nsAString& aInput, nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, uint32_t aLineNumber, bool aAllowUnsafeRules) { NS_PRECONDITION(aSheetPrincipal, "Must have principal here!"); - - NS_ASSERTION(nullptr != aBaseURI, "need base URI"); - NS_ASSERTION(nullptr != aSheetURI, "need sheet URI"); - AssertInitialState(); - + NS_PRECONDITION(aBaseURI, "need base URI"); + NS_PRECONDITION(aSheetURI, "need sheet URI"); NS_PRECONDITION(mSheet, "Must have sheet to parse into"); NS_ENSURE_STATE(mSheet); #ifdef DEBUG nsIURI* uri = mSheet->GetSheetURI(); bool equal; NS_ASSERTION(NS_SUCCEEDED(aSheetURI->Equals(uri, &equal)) && equal, "Sheet URI does not match passed URI"); NS_ASSERTION(NS_SUCCEEDED(mSheet->Principal()->Equals(aSheetPrincipal, &equal)) && equal, "Sheet principal does not match passed principal"); #endif - InitScanner(aInput, aSheetURI, aLineNumber, aBaseURI, aSheetPrincipal); + nsCSSScanner scanner(aInput, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI); + InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); int32_t ruleCount = mSheet->StyleRuleCount(); if (0 < ruleCount) { css::Rule* lastRule = nullptr; mSheet->GetStyleRuleAt(ruleCount - 1, lastRule); if (lastRule) { switch (lastRule->GetType()) { case css::Rule::CHARSET_RULE: @@ -972,22 +936,22 @@ NonMozillaVendorIdentifier(const nsAStri nsresult CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue, nsIURI* aDocURI, nsIURI* aBaseURI, nsIPrincipal* aNodePrincipal, css::StyleRule** aResult) { NS_PRECONDITION(aNodePrincipal, "Must have principal here!"); - AssertInitialState(); - - NS_ASSERTION(nullptr != aBaseURI, "need base URI"); + NS_PRECONDITION(aBaseURI, "need base URI"); // XXX line number? - InitScanner(aAttributeValue, aDocURI, 0, aBaseURI, aNodePrincipal); + nsCSSScanner scanner(aAttributeValue, 0); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aDocURI); + InitScanner(scanner, reporter, aDocURI, aBaseURI, aNodePrincipal); mSection = eCSSSection_General; // In quirks mode, allow style declarations to have braces or not // (bug 99554). bool haveBraces; if (mNavQuirkMode && GetToken(true)) { haveBraces = eCSSToken_Symbol == mToken.mType && @@ -1020,22 +984,23 @@ CSSParserImpl::ParseStyleAttribute(const nsresult CSSParserImpl::ParseDeclarations(const nsAString& aBuffer, nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, css::Declaration* aDeclaration, bool* aChanged) { + *aChanged = false; + NS_PRECONDITION(aSheetPrincipal, "Must have principal here!"); - AssertInitialState(); - - *aChanged = false; - - InitScanner(aBuffer, aSheetURI, 0, aBaseURI, aSheetPrincipal); + + nsCSSScanner scanner(aBuffer, 0); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI); + InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = eCSSSection_General; mData.AssertInitialState(); aDeclaration->ClearData(); // We could check if it was already empty, but... *aChanged = true; @@ -1058,21 +1023,21 @@ CSSParserImpl::ParseDeclarations(const n nsresult CSSParserImpl::ParseRule(const nsAString& aRule, nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, nsCOMArray<css::Rule>& aResult) { NS_PRECONDITION(aSheetPrincipal, "Must have principal here!"); - AssertInitialState(); - - NS_ASSERTION(nullptr != aBaseURI, "need base URI"); - - InitScanner(aRule, aSheetURI, 0, aBaseURI, aSheetPrincipal); + NS_PRECONDITION(aBaseURI, "need base URI"); + + nsCSSScanner scanner(aRule, 0); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI); + InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules. nsCSSToken* tk = &mToken; // Get first non-whitespace token if (!GetToken(true)) { REPORT_UNEXPECTED(PEParseRuleWSOnly); OUTPUT_ERROR(); @@ -1096,57 +1061,55 @@ CSSParserImpl::ParseRule(const nsAString nsresult CSSParserImpl::ParseProperty(const nsCSSProperty aPropID, const nsAString& aPropValue, nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, css::Declaration* aDeclaration, bool* aChanged, - bool aIsImportant) + bool aIsImportant, + bool aIsSVGMode) { NS_PRECONDITION(aSheetPrincipal, "Must have principal here!"); NS_PRECONDITION(aBaseURI, "need base URI"); NS_PRECONDITION(aDeclaration, "Need declaration to parse into!"); - AssertInitialState(); + mData.AssertInitialState(); mTempData.AssertInitialState(); aDeclaration->AssertMutable(); - InitScanner(aPropValue, aSheetURI, 0, aBaseURI, aSheetPrincipal); + nsCSSScanner scanner(aPropValue, 0); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI); + InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal); mSection = eCSSSection_General; + scanner.SetSVGMode(aIsSVGMode); *aChanged = false; // Check for unknown or preffed off properties if (eCSSProperty_UNKNOWN == aPropID || !nsCSSProps::IsEnabled(aPropID)) { NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID)); - const PRUnichar *params[] = { - propName.get() - }; - REPORT_UNEXPECTED_P(PEUnknownProperty, params); + REPORT_UNEXPECTED_P(PEUnknownProperty, propName); REPORT_UNEXPECTED(PEDeclDropped); OUTPUT_ERROR(); ReleaseScanner(); return NS_OK; } bool parsedOK = ParseProperty(aPropID); // We should now be at EOF if (parsedOK && GetToken(true)) { REPORT_UNEXPECTED_TOKEN(PEExpectEndValue); parsedOK = false; } if (!parsedOK) { NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID)); - const PRUnichar *params[] = { - propName.get() - }; - REPORT_UNEXPECTED_P(PEValueParsingError, params); + REPORT_UNEXPECTED_P(PEValueParsingError, propName); REPORT_UNEXPECTED(PEDeclDropped); OUTPUT_ERROR(); mTempData.ClearProperty(aPropID); } else { // We know we don't need to force a ValueAppended call for the new // value. So if we are not processing a shorthand, and there's // already a value for this property in the declaration at the @@ -1180,19 +1143,20 @@ CSSParserImpl::ParseMediaList(const nsSu nsMediaList* aMediaList, bool aHTMLMode) { // XXX Are there cases where the caller wants to keep what it already // has in case of parser error? aMediaList->Clear(); // fake base URI since media lists don't have URIs in them - InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr); - - AssertInitialState(); + nsCSSScanner scanner(aBuffer, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); + InitScanner(scanner, reporter, aURI, aURI, nullptr); + mHTMLMediaMode = aHTMLMode; // XXXldb We need to make the scanner not skip CSS comments! (Or // should we?) // For aHTMLMode, we used to follow the parsing rules in // http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors // which wouldn't work for media queries since they remove all but the @@ -1212,35 +1176,36 @@ CSSParserImpl::ParseMediaList(const nsSu } bool CSSParserImpl::ParseColorString(const nsSubstring& aBuffer, nsIURI* aURI, // for error reporting uint32_t aLineNumber, // for error reporting nsCSSValue& aValue) { - AssertInitialState(); - InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr); + nsCSSScanner scanner(aBuffer, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); + InitScanner(scanner, reporter, aURI, aURI, nullptr); // Parse a color, and check that there's nothing else after it. bool colorParsed = ParseColor(aValue) && !GetToken(true); OUTPUT_ERROR(); ReleaseScanner(); return colorParsed; } nsresult CSSParserImpl::ParseSelectorString(const nsSubstring& aSelectorString, nsIURI* aURI, // for error reporting uint32_t aLineNumber, // for error reporting nsCSSSelectorList **aSelectorList) { - InitScanner(aSelectorString, aURI, aLineNumber, aURI, nullptr); - - AssertInitialState(); + nsCSSScanner scanner(aSelectorString, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); + InitScanner(scanner, reporter, aURI, aURI, nullptr); bool success = ParseSelectorList(*aSelectorList, PRUnichar(0)); // We deliberately do not call OUTPUT_ERROR here, because all our // callers map a failure return to a JS exception, and if that JS // exception is caught, people don't want to see parser diagnostics; // see e.g. http://bugs.jquery.com/ticket/7535 // It would be nice to be able to save the parser diagnostics into @@ -1261,19 +1226,19 @@ CSSParserImpl::ParseSelectorString(const } already_AddRefed<nsCSSKeyframeRule> CSSParserImpl::ParseKeyframeRule(const nsSubstring& aBuffer, nsIURI* aURI, uint32_t aLineNumber) { - InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr); - - AssertInitialState(); + nsCSSScanner scanner(aBuffer, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); + InitScanner(scanner, reporter, aURI, aURI, nullptr); nsRefPtr<nsCSSKeyframeRule> result = ParseKeyframeRule(); if (GetToken(true)) { // extra garbage at the end result = nullptr; } OUTPUT_ERROR(); @@ -1285,19 +1250,19 @@ CSSParserImpl::ParseKeyframeRule(const n bool CSSParserImpl::ParseKeyframeSelectorString(const nsSubstring& aSelectorString, nsIURI* aURI, // for error reporting uint32_t aLineNumber, // for error reporting InfallibleTArray<float>& aSelectorList) { NS_ABORT_IF_FALSE(aSelectorList.IsEmpty(), "given list should start empty"); - InitScanner(aSelectorString, aURI, aLineNumber, aURI, nullptr); - - AssertInitialState(); + nsCSSScanner scanner(aSelectorString, aLineNumber); + css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI); + InitScanner(scanner, reporter, aURI, aURI, nullptr); bool success = ParseKeyframeSelectorList(aSelectorList) && // must consume entire input string !GetToken(true); OUTPUT_ERROR(); ReleaseScanner(); @@ -1312,34 +1277,34 @@ CSSParserImpl::ParseKeyframeSelectorStri //---------------------------------------------------------------------- bool CSSParserImpl::GetToken(bool aSkipWS) { for (;;) { if (!mHavePushBack) { - if (!mScanner.Next(mToken)) { + if (!mScanner->Next(mToken)) { break; } } mHavePushBack = false; if (aSkipWS && (eCSSToken_WhiteSpace == mToken.mType)) { continue; } return true; } return false; } bool CSSParserImpl::GetURLInParens(nsString& aURL) { NS_ASSERTION(!mHavePushBack, "mustn't have pushback at this point"); - if (! mScanner.NextURL(mToken)) { + if (! mScanner->NextURL(mToken)) { // EOF return false; } aURL = mToken.mIdent; if (eCSSToken_URL != mToken.mType) { // In the failure case (which gives a token of type @@ -1953,20 +1918,17 @@ CSSParserImpl::ProcessImport(const nsStr // Diagnose bad URIs even if we don't have a child loader. nsCOMPtr<nsIURI> url; // Charset will be deduced from mBaseURI, which is more or less correct. nsresult rv = NS_NewURI(getter_AddRefs(url), aURLSpec, nullptr, mBaseURI); if (NS_FAILED(rv)) { if (rv == NS_ERROR_MALFORMED_URI) { // import url is bad - const PRUnichar *params[] = { - aURLSpec.get() - }; - REPORT_UNEXPECTED_P(PEImportBadURI, params); + REPORT_UNEXPECTED_P(PEImportBadURI, aURLSpec); OUTPUT_ERROR(); } return; } if (mChildLoader) { mChildLoader->LoadChildSheet(mSheet, url, aMedia, rule); } @@ -2237,29 +2199,23 @@ CSSParserImpl::ParseFontDescriptor(nsCSS nsCSSValue value; if (descID == eCSSFontDesc_UNKNOWN) { if (NonMozillaVendorIdentifier(descName)) { // silently skip other vendors' extensions SkipDeclaration(true); return true; } else { - const PRUnichar *params[] = { - descName.get() - }; - REPORT_UNEXPECTED_P(PEUnknownFontDesc, params); + REPORT_UNEXPECTED_P(PEUnknownFontDesc, descName); return false; } } if (!ParseFontDescriptorValue(descID, value)) { - const PRUnichar *params[] = { - descName.get() - }; - REPORT_UNEXPECTED_P(PEValueParsingError, params); + REPORT_UNEXPECTED_P(PEValueParsingError, descName); return false; } if (!ExpectEndProperty()) return false; aRule->SetDesc(descID, value); return true; @@ -2386,32 +2342,32 @@ CSSParserImpl::ParseKeyframeSelectorList // : "@supports" supports_condition group_rule_body // ; bool CSSParserImpl::ParseSupportsRule(RuleAppendFunc aAppendFunc, void* aProcessData) { bool conditionMet = false; nsString condition; - mScanner.StartRecording(); + mScanner->StartRecording(); bool parsed = ParseSupportsCondition(conditionMet); if (!parsed) { - mScanner.StopRecording(); + mScanner->StopRecording(); return false; } if (!ExpectSymbol('{', true)) { REPORT_UNEXPECTED_TOKEN(PESupportsGroupRuleStart); - mScanner.StopRecording(); + mScanner->StopRecording(); return false; } UngetToken(); - mScanner.StopRecording(condition); + mScanner->StopRecording(condition); // Remove the "{" that would follow the condition. if (condition.Length() != 0) { condition.Truncate(condition.Length() - 1); } // Remove spaces from the start and end of the recorded supports condition. condition.Trim(" ", true, true, false); @@ -2515,20 +2471,17 @@ CSSParserImpl::ParseSupportsConditionInP if (!mToken.mIdent.LowerCaseEqualsLiteral("not")) { nsAutoString propertyName = mToken.mIdent; if (!ExpectSymbol(':', true)) { REPORT_UNEXPECTED_TOKEN(PEParseDeclarationNoColon); return false; } if (ExpectSymbol(')', true)) { - const PRUnichar *params[] = { - propertyName.get() - }; - REPORT_UNEXPECTED_P(PEValueParsingError, params); + REPORT_UNEXPECTED_P(PEValueParsingError, propertyName); UngetToken(); return false; } nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName, nsCSSProps::eEnabled); if (propID == eCSSProperty_UNKNOWN) { aConditionMet = false; @@ -2772,17 +2725,17 @@ CSSParserImpl::AppendRule(css::Rule* aRu } bool CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData, bool aInsideBraces) { // First get the list of selectors for the rule nsCSSSelectorList* slist = nullptr; - uint32_t linenum = mScanner.GetLineNumber(); + uint32_t linenum = mScanner->GetLineNumber(); if (! ParseSelectorList(slist, PRUnichar('{'))) { REPORT_UNEXPECTED(PEBadSelectorRSIgnored); OUTPUT_ERROR(); SkipRuleSet(aInsideBraces); return false; } NS_ASSERTION(nullptr != slist, "null selector list"); CLEAR_ERROR(); @@ -3677,17 +3630,17 @@ CSSParserImpl::ParsePseudoClassWithNthPa uint32_t truncAt = 0; if (StringBeginsWith(mToken.mIdent, NS_LITERAL_STRING("n-"))) { truncAt = 1; } else if (StringBeginsWith(mToken.mIdent, NS_LITERAL_STRING("-n-"))) { truncAt = 2; } if (truncAt != 0) { for (uint32_t i = mToken.mIdent.Length() - 1; i >= truncAt; --i) { - mScanner.Pushback(mToken.mIdent[i]); + mScanner->Pushback(mToken.mIdent[i]); } mToken.mIdent.Truncate(truncAt); } } if (eCSSToken_Ident == mToken.mType) { if (mToken.mIdent.LowerCaseEqualsLiteral("odd")) { numbers[0] = 2; @@ -4158,22 +4111,17 @@ CSSParserImpl::ParseColorComponent(uint8 return false; } if (ExpectSymbol(aStop, true)) { if (value < 0.0f) value = 0.0f; if (value > 255.0f) value = 255.0f; aComponent = NSToIntRound(value); return true; } - const PRUnichar stopString[] = { PRUnichar(aStop), PRUnichar(0) }; - const PRUnichar *params[] = { - nullptr, - stopString - }; - REPORT_UNEXPECTED_TOKEN_P(PEColorComponentBadTerm, params); + REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, aStop); return false; } bool CSSParserImpl::ParseHSLColor(nscolor& aColor, char aStop) { @@ -4232,22 +4180,17 @@ CSSParserImpl::ParseHSLColor(nscolor& aC if (l < 0.0f) l = 0.0f; if (l > 1.0f) l = 1.0f; if (ExpectSymbol(aStop, true)) { aColor = NS_HSL2RGB(h, s, l); return true; } - const PRUnichar stopString[] = { PRUnichar(aStop), PRUnichar(0) }; - const PRUnichar *params[] = { - nullptr, - stopString - }; - REPORT_UNEXPECTED_TOKEN_P(PEColorComponentBadTerm, params); + REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, aStop); return false; } bool CSSParserImpl::ParseColorOpacity(uint8_t& aOpacity) { if (!GetToken(true)) { @@ -4365,32 +4308,26 @@ CSSParserImpl::ParseDeclaration(css::Dec // Map property name to its ID and then parse the property nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName, nsCSSProps::eEnabled); if (eCSSProperty_UNKNOWN == propID || (aContext == nsCSSContextType::eCSSContext_Page && !nsCSSProps::PropHasFlags(propID, CSS_PROPERTY_APPLIES_TO_PAGE_RULE))) { // unknown property if (!NonMozillaVendorIdentifier(propertyName)) { - const PRUnichar *params[] = { - propertyName.get() - }; - REPORT_UNEXPECTED_P(PEUnknownProperty, params); + REPORT_UNEXPECTED_P(PEUnknownProperty, propertyName); REPORT_UNEXPECTED(PEDeclDropped); OUTPUT_ERROR(); } return false; } if (! ParseProperty(propID)) { // XXX Much better to put stuff in the value parsers instead... - const PRUnichar *params[] = { - propertyName.get() - }; - REPORT_UNEXPECTED_P(PEValueParsingError, params); + REPORT_UNEXPECTED_P(PEValueParsingError, propertyName); REPORT_UNEXPECTED(PEDeclDropped); OUTPUT_ERROR(); mTempData.ClearProperty(propID); mTempData.AssertInitialState(); return false; } CLEAR_ERROR(); @@ -9885,20 +9822,17 @@ CSSParserImpl::GetNamespaceIdForPrefix(c if (!prefix) { NS_RUNTIMEABORT("do_GetAtom failed - out of memory?"); } nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix); } // else no declared namespaces if (nameSpaceID == kNameSpaceID_Unknown) { // unknown prefix, dump it - const PRUnichar *params[] = { - aPrefix.get() - }; - REPORT_UNEXPECTED_P(PEUnknownNamespacePrefix, params); + REPORT_UNEXPECTED_P(PEUnknownNamespacePrefix, aPrefix); } return nameSpaceID; } void CSSParserImpl::SetDefaultNamespaceOnSelector(nsCSSSelector& aSelector) { @@ -10044,23 +9978,16 @@ nsCSSParser::SetStyleSheet(nsCSSStyleShe nsresult nsCSSParser::SetQuirkMode(bool aQuirkMode) { return static_cast<CSSParserImpl*>(mImpl)-> SetQuirkMode(aQuirkMode); } nsresult -nsCSSParser::SetSVGMode(bool aSVGMode) -{ - return static_cast<CSSParserImpl*>(mImpl)-> - SetSVGMode(aSVGMode); -} - -nsresult nsCSSParser::SetChildLoader(mozilla::css::Loader* aChildLoader) { return static_cast<CSSParserImpl*>(mImpl)-> SetChildLoader(aChildLoader); } nsresult nsCSSParser::ParseSheet(const nsAString& aInput, @@ -10113,22 +10040,24 @@ nsCSSParser::ParseRule(const nsAString& nsresult nsCSSParser::ParseProperty(const nsCSSProperty aPropID, const nsAString& aPropValue, nsIURI* aSheetURI, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, css::Declaration* aDeclaration, - bool* aChanged, - bool aIsImportant) + bool* aChanged, + bool aIsImportant, + bool aIsSVGMode) { return static_cast<CSSParserImpl*>(mImpl)-> ParseProperty(aPropID, aPropValue, aSheetURI, aBaseURI, - aSheetPrincipal, aDeclaration, aChanged, aIsImportant); + aSheetPrincipal, aDeclaration, aChanged, + aIsImportant, aIsSVGMode); } nsresult nsCSSParser::ParseMediaList(const nsSubstring& aBuffer, nsIURI* aURI, uint32_t aLineNumber, nsMediaList* aMediaList, bool aHTMLMode)
--- a/layout/style/nsCSSParser.h +++ b/layout/style/nsCSSParser.h @@ -52,19 +52,16 @@ public: // Set a style sheet for the parser to fill in. The style sheet must // implement the nsCSSStyleSheet interface. Null can be passed in to clear // out an existing stylesheet reference. nsresult SetStyleSheet(nsCSSStyleSheet* aSheet); // Set whether or not to emulate Nav quirks nsresult SetQuirkMode(bool aQuirkMode); - // Set whether or not we are in an SVG element - nsresult SetSVGMode(bool aSVGMode); - // Set loader to use for child sheets nsresult SetChildLoader(mozilla::css::Loader* aChildLoader); /** * Parse aInput into the stylesheet that was previously set by calling * SetStyleSheet. Calling this method without calling SetStyleSheet first is * an error. * @@ -108,24 +105,33 @@ public: bool* aChanged); nsresult ParseRule(const nsAString& aRule, nsIURI* aSheetURL, nsIURI* aBaseURL, nsIPrincipal* aSheetPrincipal, nsCOMArray<mozilla::css::Rule>& aResult); + // Parse the value of a single CSS property, and add or replace that + // property in aDeclaration. + // + // SVG "mapped attributes" (which correspond directly to CSS + // properties) are parsed slightly differently from regular CSS; in + // particular, units may be omitted from <length>. The 'aIsSVGMode' + // argument controls this quirk. Note that this *only* applies to + // mapped attributes, not inline styles or full style sheets in SVG. nsresult ParseProperty(const nsCSSProperty aPropID, const nsAString& aPropValue, nsIURI* aSheetURL, nsIURI* aBaseURL, nsIPrincipal* aSheetPrincipal, mozilla::css::Declaration* aDeclaration, - bool* aChanged, - bool aIsImportant); + bool* aChanged, + bool aIsImportant, + bool aIsSVGMode = false); /** * Parse aBuffer into a media list |aMediaList|, which must be * non-null, replacing its current contents. If aHTMLMode is true, * parse according to HTML rules, with commas as the most important * delimiter. Otherwise, parse according to CSS rules, with * parentheses and strings more important than commas. |aURL| and * |aLineNumber| are used for error reporting.
--- a/layout/style/nsCSSScanner.cpp +++ b/layout/style/nsCSSScanner.cpp @@ -4,44 +4,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* tokenization of CSS style sheets */ #include <math.h> // must be first due to symbol conflicts #include "nsCSSScanner.h" -#include "nsString.h" -#include "nsCRT.h" +#include "mozilla/css/ErrorReporter.h" +#include "mozilla/Likely.h" #include "mozilla/Util.h" -// for #ifdef CSS_REPORT_PARSE_ERRORS -#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include "nsIComponentManager.h" -#include "nsReadableUtils.h" -#include "nsIURI.h" -#include "nsIConsoleService.h" -#include "nsIScriptError.h" -#include "nsIStringBundle.h" -#include "nsIDocument.h" -#include "mozilla/Services.h" -#include "mozilla/css/Loader.h" -#include "nsCSSStyleSheet.h" -#include "mozilla/Preferences.h" -#include "mozilla/Likely.h" - -using namespace mozilla; - -#ifdef CSS_REPORT_PARSE_ERRORS -static bool gReportErrors = true; -static nsIConsoleService *gConsoleService; -static nsIFactory *gScriptErrorFactory; -static nsIStringBundle *gStringBundle; -#endif +using mozilla::ArrayLength; static const uint8_t IS_HEX_DIGIT = 0x01; static const uint8_t START_IDENT = 0x02; static const uint8_t IS_IDENT = 0x04; static const uint8_t IS_WHITESPACE = 0x08; static const uint8_t IS_URL_CHAR = 0x10; #define W IS_WHITESPACE @@ -159,17 +136,17 @@ HexDigitValue(int32_t ch) } nsCSSToken::nsCSSToken() { mType = eCSSToken_Symbol; } void -nsCSSToken::AppendToString(nsString& aBuffer) +nsCSSToken::AppendToString(nsString& aBuffer) const { switch (mType) { case eCSSToken_AtKeyword: aBuffer.Append(PRUnichar('@')); // fall through intentional case eCSSToken_Ident: case eCSSToken_WhiteSpace: case eCSSToken_Function: case eCSSToken_HTMLComment: @@ -245,400 +222,41 @@ nsCSSToken::AppendToString(nsString& aBu aBuffer.Append(mIdent); break; default: NS_ERROR("invalid token type"); break; } } -class DeferredCleanupRunnable : public nsRunnable -{ -public: - DeferredCleanupRunnable(nsCSSScanner* aToClean) - : mToClean(aToClean) - {} - - NS_IMETHOD Run() { - if (mToClean) { - mToClean->PerformDeferredCleanup(); - } - - return NS_OK; - } - - void Revoke() { - mToClean = nullptr; - } - -private: - nsCSSScanner* mToClean; -}; - -nsCSSScanner::nsCSSScanner() - : mReadPointer(nullptr) +nsCSSScanner::nsCSSScanner(const nsAString& aBuffer, uint32_t aLineNumber) + : mReadPointer(aBuffer.BeginReading()) + , mOffset(0) + , mCount(aBuffer.Length()) + , mPushback(mLocalPushback) + , mPushbackCount(0) + , mPushbackSize(ArrayLength(mLocalPushback)) + , mLineNumber(aLineNumber) + , mLineOffset(0) + , mRecordStartOffset(0) + , mReporter(nullptr) , mSVGMode(false) -#ifdef CSS_REPORT_PARSE_ERRORS - , mError(mErrorBuf, ArrayLength(mErrorBuf), 0) - , mInnerWindowID(0) - , mWindowIDCached(false) - , mSheet(nullptr) - , mLoader(nullptr) -#endif + , mRecording(false) { MOZ_COUNT_CTOR(nsCSSScanner); - mPushback = mLocalPushback; - mPushbackSize = ArrayLength(mLocalPushback); - // No need to init the other members, since they represent state - // which can get cleared. We'll init them every time Init() is - // called. } nsCSSScanner::~nsCSSScanner() { MOZ_COUNT_DTOR(nsCSSScanner); - Reset(); if (mLocalPushback != mPushback) { delete [] mPushback; } } -#ifdef CSS_REPORT_PARSE_ERRORS -void -nsCSSScanner::PerformDeferredCleanup() -{ - // Clean up all short term caches. - mCachedURI = nullptr; - mCachedFileName.Truncate(); - - // Release our DeferredCleanupRunnable. - mDeferredCleaner.Forget(); -} - -#define CSS_ERRORS_PREF "layout.css.report_errors" - -static int -CSSErrorsPrefChanged(const char *aPref, void *aClosure) -{ - gReportErrors = Preferences::GetBool(CSS_ERRORS_PREF, true); - return 0; -} -#endif - -/* static */ bool -nsCSSScanner::InitGlobals() -{ -#ifdef CSS_REPORT_PARSE_ERRORS - if (gConsoleService && gScriptErrorFactory) - return true; - - nsresult rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &gConsoleService); - NS_ENSURE_SUCCESS(rv, false); - - rv = CallGetClassObject(NS_SCRIPTERROR_CONTRACTID, &gScriptErrorFactory); - NS_ENSURE_SUCCESS(rv, false); - NS_ASSERTION(gConsoleService && gScriptErrorFactory, - "unexpected null pointer without failure"); - - Preferences::RegisterCallback(CSSErrorsPrefChanged, CSS_ERRORS_PREF); - CSSErrorsPrefChanged(CSS_ERRORS_PREF, nullptr); -#endif - return true; -} - -/* static */ void -nsCSSScanner::ReleaseGlobals() -{ -#ifdef CSS_REPORT_PARSE_ERRORS - Preferences::UnregisterCallback(CSSErrorsPrefChanged, CSS_ERRORS_PREF); - NS_IF_RELEASE(gConsoleService); - NS_IF_RELEASE(gScriptErrorFactory); - NS_IF_RELEASE(gStringBundle); -#endif -} - -void -nsCSSScanner::Init(const nsAString& aBuffer, - nsIURI* aURI, uint32_t aLineNumber, - nsCSSStyleSheet* aSheet, mozilla::css::Loader* aLoader) -{ - NS_PRECONDITION(!mReadPointer, "Should not have an existing input buffer!"); - - mReadPointer = aBuffer.BeginReading(); - mCount = aBuffer.Length(); - -#ifdef CSS_REPORT_PARSE_ERRORS - // If aURI is different from mCachedURI, invalidate the filename cache. - if (aURI != mCachedURI) { - mCachedURI = aURI; - mCachedFileName.Truncate(); - } -#endif // CSS_REPORT_PARSE_ERRORS - - mLineNumber = aLineNumber; - - // Reset variables that we use to keep track of our progress through the input - mOffset = 0; - mPushbackCount = 0; - mRecording = false; - -#ifdef CSS_REPORT_PARSE_ERRORS - mColNumber = 0; - mSheet = aSheet; - mLoader = aLoader; -#endif -} - -#ifdef CSS_REPORT_PARSE_ERRORS - -// @see REPORT_UNEXPECTED_EOF in nsCSSParser.cpp -#define REPORT_UNEXPECTED_EOF(lf_) \ - ReportUnexpectedEOF(#lf_) - -void -nsCSSScanner::AddToError(const nsSubstring& aErrorText) -{ - if (mError.IsEmpty()) { - mErrorLineNumber = mLineNumber; - mErrorColNumber = mColNumber; - mError = aErrorText; - } else { - mError.Append(NS_LITERAL_STRING(" ") + aErrorText); - } -} - -void -nsCSSScanner::ClearError() -{ - mError.Truncate(); -} - -void -nsCSSScanner::OutputError() -{ - if (mError.IsEmpty()) return; - - // Log it to the Error console - - if (InitGlobals() && gReportErrors) { - if (!mWindowIDCached) { - if (mSheet) { - mInnerWindowID = mSheet->FindOwningWindowInnerID(); - } - if (mInnerWindowID == 0 && mLoader) { - nsIDocument* doc = mLoader->GetDocument(); - if (doc) { - mInnerWindowID = doc->InnerWindowID(); - } - } - mWindowIDCached = true; - } - - nsresult rv; - nsCOMPtr<nsIScriptError> errorObject = - do_CreateInstance(gScriptErrorFactory, &rv); - - if (NS_SUCCEEDED(rv)) { - // Update the cached filename if needed. - if (mCachedFileName.IsEmpty()) { - if (mCachedURI) { - nsAutoCString cFileName; - mCachedURI->GetSpec(cFileName); - CopyUTF8toUTF16(cFileName, mCachedFileName); - } else { - mCachedFileName.AssignLiteral("from DOM"); - } - } - - rv = errorObject->InitWithWindowID(mError, - mCachedFileName, - EmptyString(), - mErrorLineNumber, - mErrorColNumber, - nsIScriptError::warningFlag, - "CSS Parser", - mInnerWindowID); - if (NS_SUCCEEDED(rv)) { - gConsoleService->LogMessage(errorObject); - } - } - } - ClearError(); -} - -static bool -InitStringBundle() -{ - if (gStringBundle) - return true; - - nsCOMPtr<nsIStringBundleService> sbs = - mozilla::services::GetStringBundleService(); - if (!sbs) - return false; - - nsresult rv = - sbs->CreateBundle("chrome://global/locale/css.properties", &gStringBundle); - if (NS_FAILED(rv)) { - gStringBundle = nullptr; - return false; - } - - return true; -} - -#define ENSURE_STRINGBUNDLE \ - PR_BEGIN_MACRO if (!InitStringBundle()) return; PR_END_MACRO - -// aMessage must take no parameters -void nsCSSScanner::ReportUnexpected(const char* aMessage) -{ - ENSURE_STRINGBUNDLE; - - nsXPIDLString str; - gStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), - getter_Copies(str)); - AddToError(str); -} - -void -nsCSSScanner::ReportUnexpectedParams(const char* aMessage, - const PRUnichar **aParams, - uint32_t aParamsLength) -{ - NS_PRECONDITION(aParamsLength > 0, "use the non-params version"); - ENSURE_STRINGBUNDLE; - - nsXPIDLString str; - gStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), - aParams, aParamsLength, - getter_Copies(str)); - AddToError(str); -} - -// aLookingFor is a plain string, not a format string -void -nsCSSScanner::ReportUnexpectedEOF(const char* aLookingFor) -{ - ENSURE_STRINGBUNDLE; - - nsXPIDLString innerStr; - gStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aLookingFor).get(), - getter_Copies(innerStr)); - - const PRUnichar *params[] = { - innerStr.get() - }; - nsXPIDLString str; - gStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(), - params, ArrayLength(params), - getter_Copies(str)); - AddToError(str); -} - -// aLookingFor is a single character -void -nsCSSScanner::ReportUnexpectedEOF(PRUnichar aLookingFor) -{ - ENSURE_STRINGBUNDLE; - - const PRUnichar lookingForStr[] = { - PRUnichar('\''), aLookingFor, PRUnichar('\''), PRUnichar(0) - }; - const PRUnichar *params[] = { lookingForStr }; - nsXPIDLString str; - gStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(), - params, ArrayLength(params), - getter_Copies(str)); - AddToError(str); -} - -// aMessage must take 1 parameter (for the string representation of the -// unexpected token) -void -nsCSSScanner::ReportUnexpectedToken(nsCSSToken& tok, - const char *aMessage) -{ - ENSURE_STRINGBUNDLE; - - nsAutoString tokenString; - tok.AppendToString(tokenString); - - const PRUnichar *params[] = { - tokenString.get() - }; - - ReportUnexpectedParams(aMessage, params); -} - -// aParams's first entry must be null, and we'll fill in the token -void -nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok, - const char* aMessage, - const PRUnichar **aParams, - uint32_t aParamsLength) -{ - NS_PRECONDITION(aParamsLength > 1, "use the non-params version"); - NS_PRECONDITION(aParams[0] == nullptr, "first param should be empty"); - - ENSURE_STRINGBUNDLE; - - nsAutoString tokenString; - tok.AppendToString(tokenString); - aParams[0] = tokenString.get(); - - ReportUnexpectedParams(aMessage, aParams, aParamsLength); -} - -#else - -#define REPORT_UNEXPECTED_EOF(lf_) - -#endif // CSS_REPORT_PARSE_ERRORS - -void -nsCSSScanner::Close() -{ - Reset(); - - // Schedule deferred cleanup for cached data. We want to strike a balance - // between performance and memory usage, so we only allow short-term caching. -#ifdef CSS_REPORT_PARSE_ERRORS - if (!mDeferredCleaner.IsPending()) { - mDeferredCleaner = new DeferredCleanupRunnable(this); - if (NS_FAILED(NS_DispatchToCurrentThread(mDeferredCleaner.get()))) { - // Peform the "deferred" cleanup immediately if the dispatch fails. - // This will also have the effect of clearing mDeferredCleaner. - nsCSSScanner::PerformDeferredCleanup(); - } - } -#endif -} - -void -nsCSSScanner::Reset() -{ - mReadPointer = nullptr; - - // Clean things up so we don't hold on to memory if our parser gets recycled. -#ifdef CSS_REPORT_PARSE_ERRORS - mError.Truncate(); - mInnerWindowID = 0; - mWindowIDCached = false; - mSheet = nullptr; - mLoader = nullptr; -#endif - - if (mPushback != mLocalPushback) { - delete [] mPushback; - mPushback = mLocalPushback; - mPushbackSize = ArrayLength(mLocalPushback); - } -} - // Returns -1 on error or eof int32_t nsCSSScanner::Read() { int32_t rv; if (0 < mPushbackCount) { rv = int32_t(mPushback[--mPushbackCount]); } else { @@ -655,21 +273,17 @@ nsCSSScanner::Read() rv = '\n'; } else if (rv == '\f') { rv = '\n'; } if (rv == '\n') { // 0 is a magical line number meaning that we don't know (i.e., script) if (mLineNumber != 0) ++mLineNumber; -#ifdef CSS_REPORT_PARSE_ERRORS - mColNumber = 0; - } else { - mColNumber++; -#endif + mLineOffset = 0; } } return rv; } int32_t nsCSSScanner::Peek() { @@ -1038,18 +652,18 @@ nsCSSScanner::ParseAndAppendEscape(nsStr AppendUCS4ToUTF16(ENSURE_VALID_CHAR(rv), aOutput); } else { while (i--) aOutput.Append('0'); if (IsWhitespace(ch)) Pushback(ch); } return true; - } - // "Any character except a hexidecimal digit can be escaped to + } + // "Any character except a hexadecimal digit can be escaped to // remove its special meaning by putting a backslash in front" // -- CSS1 spec section 7.1 if (ch == '\n') { if (!aInString) { // Outside of strings (which includes url() that contains a // string), escaped newlines aren't special, and just tokenize as // eCSSToken_Symbol (DELIM). Pushback(ch); @@ -1092,19 +706,16 @@ nsCSSScanner::GatherIdent(int32_t aChar, // See how much we can consume and append in one go uint32_t n = mOffset; // Count number of Ident characters that can be processed while (n < mCount && IsIdent(mReadPointer[n])) { ++n; } // Add to the token what we have so far if (n > mOffset) { -#ifdef CSS_REPORT_PARSE_ERRORS - mColNumber += n - mOffset; -#endif aIdent.Append(&mReadPointer[mOffset], n - mOffset); mOffset = n; } } aChar = Read(); if (aChar < 0) break; if (aChar == '\\') { @@ -1339,17 +950,17 @@ nsCSSScanner::SkipCComment() if (ch < 0) break; if (ch == '*') { if (LookAhead('/')) { return true; } } } - REPORT_UNEXPECTED_EOF(PECommentEOF); + mReporter->ReportUnexpectedEOF("PECommentEOF"); return false; } bool nsCSSScanner::ParseString(int32_t aStop, nsCSSToken& aToken) { aToken.mIdent.SetLength(0); aToken.mType = eCSSToken_String; @@ -1361,51 +972,44 @@ nsCSSScanner::ParseString(int32_t aStop, uint32_t n = mOffset; // Count number of characters that can be processed for (;n < mCount; ++n) { PRUnichar nextChar = mReadPointer[n]; if ((nextChar == aStop) || (nextChar == '\\') || (nextChar == '\n') || (nextChar == '\r') || (nextChar == '\f')) { break; } -#ifdef CSS_REPORT_PARSE_ERRORS - ++mColNumber; -#endif } // Add to the token what we have so far if (n > mOffset) { aToken.mIdent.Append(&mReadPointer[mOffset], n - mOffset); mOffset = n; } } int32_t ch = Read(); if (ch < 0 || ch == aStop) { break; } if (ch == '\n') { aToken.mType = eCSSToken_Bad_String; -#ifdef CSS_REPORT_PARSE_ERRORS - ReportUnexpectedToken(aToken, "SEUnterminatedString"); -#endif + mReporter->ReportUnexpected("SEUnterminatedString", aToken); break; } if (ch == '\\') { if (!ParseAndAppendEscape(aToken.mIdent, true)) { aToken.mType = eCSSToken_Bad_String; Pushback(ch); -#ifdef CSS_REPORT_PARSE_ERRORS // For strings, the only case where ParseAndAppendEscape will // return false is when there's a backslash to start an escape // immediately followed by end-of-stream. In that case, the // correct tokenization is badstring *followed* by a DELIM for // the backslash, but as far as the author is concerned, it // works pretty much the same as an unterminated string, so we // use the same error message. - ReportUnexpectedToken(aToken, "SEUnterminatedString"); -#endif + mReporter->ReportUnexpected("SEUnterminatedString", aToken); break; } } else { aToken.mIdent.Append(ch); } } return true; }
--- a/layout/style/nsCSSScanner.h +++ b/layout/style/nsCSSScanner.h @@ -4,27 +4,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* tokenization of CSS style sheets */ #ifndef nsCSSScanner_h___ #define nsCSSScanner_h___ #include "nsString.h" -#include "nsCOMPtr.h" -#include "mozilla/css/Loader.h" -#include "nsCSSStyleSheet.h" -// XXX turn this off for minimo builds -#define CSS_REPORT_PARSE_ERRORS - -// for #ifdef CSS_REPORT_PARSE_ERRORS -#include "nsXPIDLString.h" -#include "nsThreadUtils.h" -class nsIURI; +namespace mozilla { +namespace css { +class ErrorReporter; +} +} // Token types enum nsCSSTokenType { // A css identifier (e.g. foo) eCSSToken_Ident, // mIdent // A css at keyword (e.g. @foo) eCSSToken_AtKeyword, // mIdent @@ -84,89 +79,43 @@ struct nsCSSToken { bool mHasSign; // for number, percentage, and dimension nsCSSToken(); bool IsSymbol(PRUnichar aSymbol) { return bool((eCSSToken_Symbol == mType) && (mSymbol == aSymbol)); } - void AppendToString(nsString& aBuffer); + void AppendToString(nsString& aBuffer) const; }; -class DeferredCleanupRunnable; - // CSS Scanner API. Used to tokenize an input stream using the CSS // forward compatible tokenization rules. This implementation is // private to this package and is only used internally by the css // parser. class nsCSSScanner { public: - nsCSSScanner(); - ~nsCSSScanner(); - - // Init the scanner. // |aLineNumber == 1| is the beginning of a file, use |aLineNumber == 0| // when the line number is unknown. - void Init(const nsAString& aBuffer, - nsIURI* aURI, uint32_t aLineNumber, - nsCSSStyleSheet* aSheet, mozilla::css::Loader* aLoader); - void Close(); + nsCSSScanner(const nsAString& aBuffer, uint32_t aLineNumber); + ~nsCSSScanner(); - static bool InitGlobals(); - static void ReleaseGlobals(); - + void SetErrorReporter(mozilla::css::ErrorReporter* aReporter) { + mReporter = aReporter; + } // Set whether or not we are processing SVG void SetSVGMode(bool aSVGMode) { mSVGMode = aSVGMode; } bool IsSVGMode() const { return mSVGMode; } -#ifdef CSS_REPORT_PARSE_ERRORS - // Clean up any reclaimable cached resources. - void PerformDeferredCleanup(); - - void AddToError(const nsSubstring& aErrorText); - void OutputError(); - void ClearError(); - - // aMessage must take no parameters - void ReportUnexpected(const char* aMessage); - -private: - void Reset(); - - void ReportUnexpectedParams(const char* aMessage, - const PRUnichar** aParams, - uint32_t aParamsLength); - -public: - template<uint32_t N> - void ReportUnexpectedParams(const char* aMessage, - const PRUnichar* (&aParams)[N]) - { - return ReportUnexpectedParams(aMessage, aParams, N); - } - // aLookingFor is a plain string, not a format string - void ReportUnexpectedEOF(const char* aLookingFor); - // aLookingFor is a single character - void ReportUnexpectedEOF(PRUnichar aLookingFor); - // aMessage must take 1 parameter (for the string representation of the - // unexpected token) - void ReportUnexpectedToken(nsCSSToken& tok, const char *aMessage); - // aParams's first entry must be null, and we'll fill in the token - void ReportUnexpectedTokenParams(nsCSSToken& tok, - const char* aMessage, - const PRUnichar **aParams, - uint32_t aParamsLength); -#endif - - uint32_t GetLineNumber() { return mLineNumber; } + uint32_t GetLineNumber() const { return mLineNumber; } + uint32_t GetColumnNumber() const { return mOffset - mLineOffset + 1; } // Get the next token. Return false on EOF. aTokenResult // is filled in with the data for the token. bool Next(nsCSSToken& aTokenResult); // Get the next token that may be a string or unquoted URL bool NextURL(nsCSSToken& aTokenResult); @@ -202,34 +151,25 @@ protected: bool ParseURange(int32_t aChar, nsCSSToken& aResult); bool SkipCComment(); bool GatherIdent(int32_t aChar, nsString& aIdent); const PRUnichar *mReadPointer; uint32_t mOffset; uint32_t mCount; + PRUnichar* mPushback; int32_t mPushbackCount; int32_t mPushbackSize; PRUnichar mLocalPushback[4]; uint32_t mLineNumber; + uint32_t mLineOffset; + uint32_t mRecordStartOffset; + + mozilla::css::ErrorReporter *mReporter; // True if we are in SVG mode; false in "normal" CSS bool mSVGMode; bool mRecording; - uint32_t mRecordStartOffset; - -#ifdef CSS_REPORT_PARSE_ERRORS - nsRevocableEventPtr<DeferredCleanupRunnable> mDeferredCleaner; - nsCOMPtr<nsIURI> mCachedURI; // Used to invalidate the cached filename. - nsString mCachedFileName; - uint32_t mErrorLineNumber, mColNumber, mErrorColNumber; - nsFixedString mError; - PRUnichar mErrorBuf[200]; - uint64_t mInnerWindowID; - bool mWindowIDCached; - nsCSSStyleSheet* mSheet; - mozilla::css::Loader* mLoader; -#endif }; #endif /* nsCSSScanner_h___ */
--- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -2212,29 +2212,26 @@ BuildStyleRule(nsCSSProperty aProperty, nsAutoPtr<css::Declaration> declaration(new css::Declaration()); declaration->InitializeEmpty(); bool changed; // ignored, but needed as outparam for ParseProperty nsIDocument* doc = aTargetElement->OwnerDoc(); nsCOMPtr<nsIURI> baseURI = aTargetElement->GetBaseURI(); nsCSSParser parser(doc->CSSLoader()); - if (aUseSVGMode) { - parser.SetSVGMode(true); - } - nsCSSProperty propertyToCheck = nsCSSProps::IsShorthand(aProperty) ? nsCSSProps::SubpropertyEntryFor(aProperty)[0] : aProperty; // Get a parser, parse the property, and check for CSS parsing errors. // If any of these steps fails, we bail out and delete the declaration. if (NS_FAILED(parser.ParseProperty(aProperty, aSpecifiedValue, doc->GetDocumentURI(), baseURI, aTargetElement->NodePrincipal(), - declaration, &changed, false)) || + declaration, &changed, false, + aUseSVGMode)) || // check whether property parsed without CSS parsing errors !declaration->HasNonImportantValueFor(propertyToCheck)) { NS_WARNING("failure in BuildStyleRule"); return nullptr; } nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration.forget()); return rule.forget();
new file mode 100644 --- /dev/null +++ b/layout/svg/crashtests/768087-1.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<html> +<body onload="setTimeout(function() { document.body.innerHTML = '<span>x<svg viewbox=\'0 0 30 40\' ></svg></span>'; }, 0);"></body> +</html>
new file mode 100644 --- /dev/null +++ b/layout/svg/crashtests/778492-1.svg @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<svg width="1cm" viewBox="0 0 1 1" xmlns="http://www.w3.org/2000/svg"> +<line x2="100" y2="100"/> +</svg>
new file mode 100644 --- /dev/null +++ b/layout/svg/crashtests/780764-1.svg @@ -0,0 +1,18 @@ +<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait"> + +<marker id="marker"><path d="M100,0 l100,100 200,200" filter="url(#filter)"/></marker> + +<filter id="filter"/> + +<path d="M100,0 l100,100 200,200" marker-mid="url(#marker)"/> + +<script> +window.addEventListener("load", function() { + setTimeout(function() { + document.getElementById("filter").style.fontWeight = "bold"; + document.documentElement.removeAttribute("class"); + }, 200); +}, false); +</script> + +</svg>
--- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -131,13 +131,16 @@ load 732836-1.svg load 740627-1.svg load 740627-2.svg load 757704-1.svg load 757718-1.svg load 767056-1.svg load 768351.svg load 780963-1.html load 757751-1.svg +load 768087-1.html +load 778492-1.svg load 779971-1.svg +load 780764-1.svg load 782141-1.svg load 784061-1.svg load 790072.svg load 791826-1.svg
--- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c @@ -163,522 +163,522 @@ static void fsmdef_update_calltype (fsm_ /* * TODO <emannion> Update events for correct JSEP transitions * Instead of providing events for all states */ static sm_function_t fsmdef_function_table[FSMDEF_S_MAX][CC_MSG_MAX] = { /* FSMDEF_S_IDLE ------------------------------------------------------------ */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_idle_setup, // New incoming - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* FSMDEF_E_FEATURE */ fsmdef_ev_idle_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_idle_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_default, - /* FSMDEF_E_LINE */ fsmdef_ev_idle_offhook, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_idle_dialstring, // new outgoing - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_idle_setup, // New incoming + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_default, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, + /* CC_MSG_FEATURE */ fsmdef_ev_idle_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_idle_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_default, + /* CC_MSG_LINE */ fsmdef_ev_idle_offhook, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_idle_dialstring, // new outgoing + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_COLLECT_INFO ---------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_collectinginfo_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_dialstring, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_collectinginfo_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_dialstring, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_CALL_SENT ------------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_proceeding, - /* FSMDEF_E_ALERTING */ fsmdef_ev_out_alerting, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_connected, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_callsent_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_callsent_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_proceeding, + /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, + /* CC_MSG_CONNECTED */ fsmdef_ev_connected, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_OUTGOING_PROCEEDING --------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_out_alerting, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_connected, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_callsent_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_callsent_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, + /* CC_MSG_CONNECTED */ fsmdef_ev_connected, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_KPML_COLLECT_INFO ----------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_out_alerting, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_connected, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_callsent_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_collectinginfo_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_digit_begin, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, + /* CC_MSG_CONNECTED */ fsmdef_ev_connected, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_collectinginfo_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_digit_begin, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_OUTGOING_ALERTING ----------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_out_alerting, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_connected, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_callsent_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_callsent_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_out_alerting, + /* CC_MSG_CONNECTED */ fsmdef_ev_connected, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_callsent_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_callsent_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_INCOMING_ALERTING ----------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_inalerting_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_inalerting_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_inalerting_offhook, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_inalerting_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_inalerting_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_inalerting_offhook, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_CONNECTING ------------------------------------------------------ */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_connected_ack, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_connecting_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_connected_line, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_connected_ack, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_connected_line, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_JOINING --------------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_joining_connected_ack, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_connecting_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_joining_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_connected_line, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_joining_connected_ack, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_connecting_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_joining_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_connected_line, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_CONNECTED ------------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_connected_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_connected_line, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_connected_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_connected_line, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_CONNECTED_MEDIA_PEND ------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_connected_media_pend_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_connected_media_pend_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_connected_line, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_connected_media_pend_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_connected_media_pend_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_connected_line, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_RELEASING ------------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_releasing_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_release_complete, - /* FSMDEF_E_FEATURE */ fsmdef_ev_releasing_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_releasing_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_connected_line, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_releasing_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete, + /* CC_MSG_FEATURE */ fsmdef_ev_releasing_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_releasing_onhook, + /* CC_MSG_LINE */ fsmdef_ev_connected_line, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_HOLD_PENDING ---------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_holding_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_hold_pending_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_hold_pending_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_hold_pending_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_hold_pending_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_HOLDING --------------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_holding_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_holding_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_holding_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_holding_offhook, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_holding_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_holding_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_holding_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_holding_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_holding_offhook, + /* CC_MSG_ONHOOK */ fsmdef_ev_holding_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_RESUME_PENDING -------------------------------------------------- */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_resume_pending_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_resume_pending_feature_ack, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_resume_pending_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_resume_pending_feature_ack, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate }, /* FSMDEF_S_PRESERVED ------------------------------------------------------ */ { - /* FSMDEF_E_SETUP */ fsmdef_ev_default, - /* FSMDEF_E_SETUP_ACK */ fsmdef_ev_default, - /* FSMDEF_E_PROCEEDING */ fsmdef_ev_default, - /* FSMDEF_E_ALERTING */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED */ fsmdef_ev_default, - /* FSMDEF_E_CONNECTED_ACK */ fsmdef_ev_default, - /* FSMDEF_E_RELEASE */ fsmdef_ev_release, - /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default, - /* FSMDEF_E_FEATURE */ fsmdef_ev_preserved_feature, - /* FSMDEF_E_FEATURE_ACK */ fsmdef_ev_default, - /* FSMDEF_E_OFFHOOK */ fsmdef_ev_default, - /* FSMDEF_E_ONHOOK */ fsmdef_ev_onhook, - /* FSMDEF_E_LINE */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_BEGIN */ fsmdef_ev_default, - /* FSMDEF_E_DIGIT_END */ fsmdef_ev_default, - /* FSMDEF_E_DIALSTRING */ fsmdef_ev_default, - /* FSMDEF_E_MWI */ fsmdef_ev_default, - /* FSMDEF_E_SESSION_AUDIT */ fsmdef_ev_session_audit, - /* FSMDEF_E_CREATEOFFER */ fsmdef_ev_createoffer, - /* FSMDEF_E_CREATEANSWER */ fsmdef_ev_createanswer, - /* FSMDEF_E_SETLOCALDESC */ fsmdef_ev_setlocaldesc, - /* FSMDEF_E_SETREMOTEDESC */ fsmdef_ev_setremotedesc, - /* FSMDEF_E_LOCALDESC */ fsmdef_ev_localdesc, - /* FSMDEF_E_REMOTEDESC */ fsmdef_ev_remotedesc, - /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, - /* FSMDEF_E_ADDSTREAM */ fsmdef_ev_addstream, - /* FSMDEF_E_REMOVESTREAM */ fsmdef_ev_removestream, - /* FAMDEF_E_ADDCANDIDATE */ fsmdef_ev_addcandidate + /* CC_MSG_SETUP */ fsmdef_ev_default, + /* CC_MSG_SETUP_ACK */ fsmdef_ev_default, + /* CC_MSG_PROCEEDING */ fsmdef_ev_default, + /* CC_MSG_ALERTING */ fsmdef_ev_default, + /* CC_MSG_CONNECTED */ fsmdef_ev_default, + /* CC_MSG_CONNECTED_ACK */ fsmdef_ev_default, + /* CC_MSG_RELEASE */ fsmdef_ev_release, + /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default, + /* CC_MSG_FEATURE */ fsmdef_ev_preserved_feature, + /* CC_MSG_FEATURE_ACK */ fsmdef_ev_default, + /* CC_MSG_OFFHOOK */ fsmdef_ev_default, + /* CC_MSG_ONHOOK */ fsmdef_ev_onhook, + /* CC_MSG_LINE */ fsmdef_ev_default, + /* CC_MSG_DIGIT_BEGIN */ fsmdef_ev_default, + /* CC_MSG_DIGIT_END */ fsmdef_ev_default, + /* CC_MSG_DIALSTRING */ fsmdef_ev_default, + /* CC_MSG_MWI */ fsmdef_ev_default, + /* CC_MSG_SESSION_AUDIT */ fsmdef_ev_session_audit, + /* CC_MSG_CREATEOFFER */ fsmdef_ev_createoffer, + /* CC_MSG_CREATEANSWER */ fsmdef_ev_createanswer, + /* CC_MSG_SETLOCALDESC */ fsmdef_ev_setlocaldesc, + /* CC_MSG_SETREMOTEDESC */ fsmdef_ev_setremotedesc, + /* CC_MSG_LOCALDESC */ fsmdef_ev_localdesc, + /* CC_MSG_REMOTEDESC */ fsmdef_ev_remotedesc, + /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection, + /* CC_MSG_ADDSTREAM */ fsmdef_ev_addstream, + /* CC_MSG_REMOVESTREAM */ fsmdef_ev_removestream, + /* CC_MSG_ADDCANDIDATE */ fsmdef_ev_addcandidate } }; static sm_table_t fsmdef_sm_table; sm_table_t *pfsmdef_sm_table = &fsmdef_sm_table; /*-------------------------------------------------------------------------- * Global data @@ -2764,17 +2764,17 @@ fsmdef_dialstring (fsm_fcb_t *fcb, const default: if (dialstring) { dcb->caller_id.called_number = strlib_update(dcb->caller_id.called_number, dialstring); } break; } - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE); + cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); if (cause != CC_CAUSE_OK) { FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); /* Force clean up call without sending release */ return (fsmdef_release(fcb, cause, FALSE)); } /* Build SDP for sending out */ cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); @@ -2927,17 +2927,17 @@ fsmdef_ev_createoffer (sm_event_t *event dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN, dcb->digest, FSMDEF_MAX_DIGEST_LEN); if (vcm_res) { FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); return SM_RC_END; } - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE); + cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); if (cause != CC_CAUSE_OK) { ui_create_offer(evCreateOfferError, line, call_id, dcb->caller_id.call_instance_id, NULL); FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); return (fsmdef_release(fcb, cause, FALSE)); } cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); if (cause != CC_CAUSE_OK) { @@ -2974,16 +2974,19 @@ fsmdef_ev_createanswer (sm_event_t *even const char *called_number = "1234"; cc_causes_t lsm_rc; cc_msgbody_t *part; uint32_t body_length; char *ufrag = NULL; char *ice_pwd = NULL; short vcm_res; session_data_t *sess_data_p; + boolean has_audio; + boolean has_video; + boolean has_data; FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); if (!sdpmode) { return (fsmdef_release(fcb, cause, FALSE)); } @@ -3031,31 +3034,37 @@ fsmdef_ev_createanswer (sm_event_t *even dcb->digest, FSMDEF_MAX_DIGEST_LEN); if (vcm_res) { FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); return SM_RC_END; } /* + * Determine what media types are offered, used to create matching local SDP + * for negotiation. + */ + gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data); + + /* * The sdp member of the dcb has local and remote sdp * this next function fills in the local part */ - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE); + cause = gsmsdp_create_local_sdp(dcb, FALSE, has_audio, has_video, has_data, FALSE); if (cause != CC_CAUSE_OK) { ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); // Force clean up call without sending release return (fsmdef_release(fcb, cause, FALSE)); } /* TODO(ekr@rtfm.com): The second true is because we are acting as if we are processing an offer. The first, however, is for an initial offer and we may want to set that conditionally. */ - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, FALSE); + cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, FALSE, TRUE); if (cause != CC_CAUSE_OK) { ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL); return (fsmdef_release(fcb, cause, FALSE)); } cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); if (cause != CC_CAUSE_OK) { @@ -3242,26 +3251,26 @@ fsmdef_ev_setremotedesc(sm_event_t *even * for negotiation. */ gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data); /* * The sdp member of the dcb has local and remote sdp * this next function fills in the local part */ - cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data); + cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data, FALSE); if (cause != CC_CAUSE_OK) { ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SETREMOTEDESCERROR); FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); // Force clean up call without sending release return (fsmdef_release(fcb, cause, FALSE)); } - cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, TRUE); + cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, TRUE, FALSE); if (cause != CC_CAUSE_OK) { ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id, NULL, PC_SETREMOTEDESCERROR); return (fsmdef_release(fcb, cause, FALSE)); } gsmsdp_clean_media_list(dcb); @@ -3436,17 +3445,16 @@ fsmdef_ev_addstream(sm_event_t *event) { * default streams. When multiple streams > 2 are supported this * will be re-implemented. */ if (msg->data.track.media_type == VIDEO) { dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV; dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_stream = msg->data.track.stream_id; dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_track = msg->data.track.track_id; - dcb->video_pref = SDP_DIRECTION_SENDRECV; } else if (msg->data.track.media_type == AUDIO) { dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV; dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_stream = msg->data.track.stream_id; dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_track = msg->data.track.track_id; } else { return (SM_RC_END); } @@ -3479,23 +3487,23 @@ fsmdef_ev_removestream(sm_event_t *event return SM_RC_CLEANUP; } /* * This is temporary code to allow configuration of the two * default streams. When multiple streams > 2 are supported this * will be re-implemented. */ - if (msg->data.track.media_type == VIDEO) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE; - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_INACTIVE; + if (msg->data.track.media_type == AUDIO) { + dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; + dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; dcb->video_pref = SDP_DIRECTION_SENDRECV; - } else if (msg->data.track.media_type == AUDIO) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; + } else if (msg->data.track.media_type == VIDEO) { + dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; + dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; } else { return (SM_RC_END); } return (SM_RC_END); } static sm_rcs_t @@ -7746,17 +7754,17 @@ fsmdef_cfwd_clear_ccm (fsm_fcb_t *fcb) FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__)); // to clear CFA in CCM mode... only put service uri... no dialstring. fsmdef_append_dialstring_to_feature_uri(dcb, NULL); // From here on all we need to do is send INVITE out. // Since, its not a real call there is no need to update UI etc. // Response to this call will be 5xx so it will be released by the SIP stack. - cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE); + cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE); if (cause != CC_CAUSE_OK) { FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR)); return (fsmdef_release(fcb, cause, dcb->send_release)); } /* Build SDP for sending out */ cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body); if (cause != CC_CAUSE_OK) {
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c @@ -77,17 +77,17 @@ static cc_causes_t gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp); static void gsmsdp_set_media_capability(fsmdef_media_t *media, const cc_media_cap_t *media_cap); static fsmdef_media_t * gsmsdp_add_media_line(fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type); + cpr_ip_type addr_type, boolean offer); extern cc_media_cap_table_t g_media_table; extern vcm_media_payload_type_t vcmRtpToMediaPayload (int32_t ptype, int32_t dynamic_ptype_value, uint16_t mode); extern boolean g_disable_mass_reg_debug_print; /** @@ -119,91 +119,98 @@ static const cc_media_cap_table_t *gsmsd GSM_ERR_MSG(GSM_L_C_F_PREFIX"media table malloc failed.\n", dcb_p->line, dcb_p->call_id, fname); return NULL; } } *(dcb_p->media_cap_tbl) = g_media_table; - if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) { - // do not enable video - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - } - - if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n", - dcb_p->line, dcb_p->call_id, fname); - } - } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) { - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; - } - - if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; - DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n", - dcb_p->line, dcb_p->call_id, fname); - } - } // else if requested is SENDRECV just go by capability - /* * Turn off two default streams, this is temporary * until we can handle multiple streams properly */ if (sdpmode) { - dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; - dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE; - dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE; + dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; + dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; + dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE; } else { dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE; + + if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) { + // do not enable video + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE; + } + + if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) { + if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; + } + + if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) { + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; + DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n", + dcb_p->line, dcb_p->call_id, fname); + } + } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) { + if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) { + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref; + } + + if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) { + dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE; + DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n", + dcb_p->line, dcb_p->call_id, fname); + } + } // else if requested is SENDRECV just go by capability } return (dcb_p->media_cap_tbl); } /* - * Process constraints only related to media capabilities. i.e OfferToReceiveAudio, OfferToReceiveVideo + * Process a single constraint for one media capablity */ -void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints) { +void gsmsdp_process_cap_constraint(cc_media_cap_t *cap, + const char *constraint) { + /* Check constraint string for values "TRUE" or "FALSE" + (currently set in PeerConnectionImpl.cpp, with only + two possible hardcoded values). + TODO -- The values that constraints can take are + fairly narrow and enumerated; they should probably + use an enumeration rather than a string. See bug 811360. + */ + if (constraint[0] == 'F') { + cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV; + } else if (constraint[0] == 'T') { + cap->support_direction |= SDP_DIRECTION_FLAG_RECV; + } +} + +/* + * Process constraints only related to media capabilities., i.e + * OfferToReceiveAudio, OfferToReceiveVideo + */ +void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, + const cc_media_constraints_t* constraints) { int i = 0; for (i=0; i<constraints->constraint_count; i++) { - - if (strcmp(constraints_table[OfferToReceiveAudio].name, constraints->constraints[i]->name) == 0) { - if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDONLY; - } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 && - TRUE == dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV; - } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) { - dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY; - } - } - - if (strcmp("OfferToReceiveVideo", constraints->constraints[i]->name) == 0) { - if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDONLY; - } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 && - TRUE == dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV; - } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) { - dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE; - dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY; - } + if (strcmp(constraints_table[OfferToReceiveAudio].name, + constraints->constraints[i]->name) == 0) { + gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1], + constraints->constraints[i]->value); + } else if (strcmp(constraints_table[OfferToReceiveVideo].name, + constraints->constraints[i]->name) == 0) { + gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1], + constraints->constraints[i]->value); } } - } /** * Sets up the media track table * * @param[in]dcb - pointer to the fsmdef_dcb_t * * @return - pointer to the the media track table for session @@ -1961,35 +1968,39 @@ gsmsdp_add_default_audio_formats_to_loca if (sdp_add_media_payload_type(local_sdp_p, level, (uint16_t)local_media_types[type_cnt], SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding media payload type failed\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); } - gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p, + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p, level, (uint16_t)local_media_types[type_cnt]); + } } /* * add the avt media type */ if (local_avt_payload_type > RTP_NONE) { if (sdp_add_media_payload_type(local_sdp_p, level, local_avt_payload_type, SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed\n", dcb_p->line, dcb_p->call_id, fname); } - gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level, - local_avt_payload_type); - if (media) { - media->avt_payload_type = local_avt_payload_type; + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level, + local_avt_payload_type); + if (media) { + media->avt_payload_type = local_avt_payload_type; + } } } } /* * gsmsdp_add_default_video_formats_to_local_sdp * * Description: @@ -2070,18 +2081,20 @@ gsmsdp_add_default_video_formats_to_loca if (sdp_add_media_payload_type(local_sdp_p, level, (uint16_t)video_media_types[type_cnt], SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) { GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR(1)\n", line, call_id, fname); } - gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p, - level, (uint16_t)video_media_types[type_cnt]); + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p, + level, (uint16_t)video_media_types[type_cnt]); + } } } /** * This function sets the mid attr at the media level * and labels the relevant media streams when phone is * operating in a dual stack mode * @@ -2263,17 +2276,20 @@ gsmsdp_update_local_sdp_media (fsmdef_dc result = sdp_insert_media_line(sdp_p, level); if (result != SDP_SUCCESS) { GSM_ERR_MSG(GSM_L_C_F_PREFIX"Inserting media line to Sdp failed\n", dcb_p->line, dcb_p->call_id, fname); return; } - gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr); + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr); + } + (void) sdp_set_media_type(sdp_p, level, media->type); (void) sdp_set_media_portnum(sdp_p, level, port, media->sctp_port); /* Set media transport and crypto attributes if it is for SRTP */ gsmsdp_update_local_sdp_media_transport(dcb_p, sdp_p, media, transport, all_formats); @@ -2616,17 +2632,17 @@ gsmsdp_get_remote_avt_payload_type (uint * * Returns: * * payload > 0: negotiated payload * <= 0: negotiation failed */ static int gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p, - fsmdef_media_t *media, boolean offer, boolean initial_offer) + fsmdef_media_t *media, boolean offer, boolean initial_offer, uint16 media_level) { static const char fname[] = "gsmsdp_negotiate_codec"; rtp_ptype pref_codec = RTP_NONE; uint16_t i; uint16_t j; int *master_list_p = NULL; int *slave_list_p = NULL; DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE; @@ -2654,17 +2670,17 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dc int remote_dynamic_payload_type_value = RTP_NONE; int32_t payload_types_count = 0; // count for allocating right amout // of memory for media->paylaods if (!dcb_p || !sdp_p || !media) { return (RTP_NONE); } - level = media->level; + level = media_level; attr_label = sdp_attr_get_simple_string(sdp_p->dest_sdp, SDP_ATTR_LABEL, level, 0, 1); if (attr_label != NULL) { if (strcmp(attr_label, MIX_NEAREND_STRING) == 0) { dcb_p->session = WHISPER_COACHING; } } @@ -3875,41 +3891,59 @@ gsmsdp_negotiate_remove_media_line (fsmd /* * This media line is to be removed. */ return (TRUE); } /* + * Find a media line based on the media type. + */ +fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e media_type) { + + fsmdef_media_t *media = NULL; + + /* + * search the all entries that has a valid media and matches the media type + */ + GSMSDP_FOR_ALL_MEDIA(media, dcb_p) { + if (media->type == media_type) { + /* found a match */ + return (media); + } + } + return (NULL); +} + +/* * gsmsdp_negotiate_media_lines * * Description: * * Walk down the media lines provided in the remote sdp. Compare each * media line to the corresponding media line in the local sdp. If * the media line does not exist in the local sdp, add it. If the media * line exists in the local sdp but is different from the remote sdp, * change the local sdp to match the remote sdp. If the media line * is an AUDIO format, negotiate the codec and update the local sdp - * as needed. We will reject all media lines that are not AUDIO and we - * will only accept the first AUDIO media line located. + * as needed. * * Parameters: * * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are being negotiated * sdp_p - Pointer to the local and remote SDP * initial_offer - Boolean indicating if the remote SDP came in the first OFFER of this session * offer - Boolean indicating if the remote SDP came in an OFFER. * notify_stream_added - Boolean indicating the UI should be notified of streams added * */ cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, - boolean initial_offer, boolean offer, boolean notify_stream_added) +gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, + boolean offer, boolean notify_stream_added, boolean create_answer) { static const char fname[] = "gsmsdp_negotiate_media_lines"; cc_causes_t cause = CC_CAUSE_OK; uint16_t num_m_lines = 0; uint16_t num_local_m_lines = 0; uint16_t i = 0; sdp_media_e media_type; fsmdef_dcb_t *dcb_p = fcb_p->dcb; @@ -3952,22 +3986,49 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); return (CC_CAUSE_NO_MEDIA); } /* * Process each media line in the remote SDP */ for (i = 1; i <= num_m_lines; i++) { - unsupported_line = FALSE; /* assume line will be supported */ new_media = FALSE; media = NULL; media_type = sdp_get_media_type(sdp_p->dest_sdp, i); + /* + * Only perform these checks when called from createanswer + * because at this point we are concerned as to which m= lines + * have been created in the answer. + */ + if (create_answer) { + + /* Since the incoming SDP might not be in the same order as + our media, we find them by type rather than location + for this check. Note that we're not checking for the + value of any _particular_ m= section; we're just checking + whether (at least) one of the specified type exists. */ + media = gsmsdp_find_media_by_media_type(dcb_p, media_type); + + if (media_type == SDP_MEDIA_AUDIO && !media) { + /* continue if answer will not add this m= line */ + continue; + } + + if (media_type == SDP_MEDIA_VIDEO && !media) { + continue; + } + + if (media_type == SDP_MEDIA_APPLICATION && !media) { + continue; + } + } + port = (uint16_t) sdp_get_media_portnum(sdp_p->dest_sdp, i); GSM_DEBUG(DEB_L_C_F_PREFIX"Port is %d at %d %d\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), port, i, initial_offer); switch (media_type) { case SDP_MEDIA_AUDIO: case SDP_MEDIA_VIDEO: @@ -3986,17 +4047,19 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t break; } /* * Find the corresponding media entry in the dcb to see * this has been negiotiated previously (from the * last offer/answer session). */ - media = gsmsdp_find_media_by_level(dcb_p, i); + if(!create_answer) + media = gsmsdp_find_media_by_level(dcb_p, i); + if (media == NULL) { /* No previous media, negotiate adding new media line. */ media = gsmsdp_negotiate_add_media_line(dcb_p, media_type, i, port, offer); if (media == NULL) { /* new one can not be added */ unsupported_line = TRUE; break; @@ -4024,16 +4087,21 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t } else { /* The media at the same level but not the expected type */ GSM_ERR_MSG(GSM_L_C_F_PREFIX"mismatch media type at %d\n", dcb_p->line, dcb_p->call_id, fname, i); unsupported_line = TRUE; break; } + /* Do not negotiate if media is set to inactive */ + if (SDP_DIRECTION_INACTIVE == media->direction) { + break; + } + /* Reset multicast flag and port */ media->is_multicast = FALSE; media->multicast_port = 0; /* Update remote address */ media->previous_sdp.dest_addr = media->dest_addr; media->dest_addr = remote_addr; @@ -4085,32 +4153,32 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t } /* * Negotiate RTP/SRTP. The result is the media transport * which could be RTP/SRTP or fail. */ transport = gsmsdp_negotiate_media_transport(dcb_p, sdp_p, offer, media, - &crypto_inst); + &crypto_inst, i); if (transport == SDP_TRANSPORT_INVALID) { /* unable to negotiate transport */ unsupported_line = TRUE; GSM_DEBUG(DEB_L_C_F_PREFIX"transport mismatch at %d\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); break; } /* Don't need to negotiate a codec for an m= applicaton line */ if (SDP_MEDIA_APPLICATION != media_type) { /* * Negotiate to a single codec */ - if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer) == + if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer, i) == RTP_NONE) { /* unable to negotiate codec */ unsupported_line = TRUE; /* Failed codec negotiation */ cause = CC_CAUSE_PAYLOAD_MISMATCH; GSM_DEBUG(DEB_L_C_F_PREFIX"codec mismatch at %d\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i); break; @@ -4120,17 +4188,17 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t } /* * Both media transport (RTP/SRTP) and codec are * now negotiated to common ones, update transport * parameters to be used for SRTP, if there is any. */ gsmsdp_update_negotiated_transport(dcb_p, sdp_p, media, - crypto_inst, transport); + crypto_inst, transport, i); GSM_DEBUG(DEB_F_PREFIX"local transport after updating negotiated: %d\n",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1)); /* * Add to or update media line to the local SDP as needed. */ if (gsmsdp_is_multicast_address(media->dest_addr)) { /* * Multicast, if the address is multicast * then change the local sdp and do the necessary @@ -4173,17 +4241,17 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t unsupported_line = TRUE; update_local_ret_value = TRUE; } /* * Negotiate rtcp-mux */ - sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, media->level, + sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, i, 0, SDP_ATTR_RTCP_MUX, 1, &rtcp_mux); if (SDP_SUCCESS == sdp_res) { media->rtcp_mux = TRUE; } if (!unsupported_line) { @@ -4545,17 +4613,17 @@ gsmsdp_set_media_capability (fsmdef_medi * add a new line otherwise return NULL. * * @pre (dcb_p not_eq NULL) * @pre (media_cap not_eq NULL) */ static fsmdef_media_t * gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap, uint8_t cap_index, uint16_t level, - cpr_ip_type addr_type) + cpr_ip_type addr_type, boolean offer) { static const char fname[] = "gsmsdp_add_media_line"; cc_action_data_t data; fsmdef_media_t *media = NULL; int i=0; int rtcpmux = 0; int sctp_port = 0; @@ -4577,105 +4645,119 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb /* associate this media line to the capability entry */ media->cap_index = cap_index; /* keep the media cap entry index */ /* override the direction for special feature */ gsmsdp_feature_overide_direction(dcb_p, media); if (media->support_direction == SDP_DIRECTION_INACTIVE) { GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive" " no media added\n", - DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); - gsmsdp_remove_media(dcb_p, media); - return (NULL); + DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname)); + + /* + * For an answer, SDP_DIRECTION_INACTIVE will now add an m= + * line but it is disabled. + */ + if (!offer) { + media->src_port = 0; + } else { + gsmsdp_remove_media(dcb_p, media); + return (NULL); + } } - /* - * Get the local RTP port. The src port will be set in the dcb - * within the call to cc_call_action(CC_ACTION_OPEN_RCV) - */ - data.open_rcv.is_multicast = FALSE; - data.open_rcv.listen_ip = ip_addr_invalid; - data.open_rcv.port = 0; - data.open_rcv.keep = FALSE; - /* - * Indicate type of media (audio/video etc) becase some for - * supporting video over vieo, the port is obtained from other - * entity. - */ - data.open_rcv.media_type = media->type; - data.open_rcv.media_refid = media->refid; - if (cc_call_action(dcb_p->call_id, dcb_p->line, - CC_ACTION_OPEN_RCV, - &data) != CC_RC_SUCCESS) { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); - } - - /* allocate port successful, save the port */ - - media->src_port = data.open_rcv.port; - - if(media_cap->type == SDP_MEDIA_APPLICATION) { + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + /* + * Get the local RTP port. The src port will be set in the dcb + * within the call to cc_call_action(CC_ACTION_OPEN_RCV) + */ + data.open_rcv.is_multicast = FALSE; + data.open_rcv.listen_ip = ip_addr_invalid; + data.open_rcv.port = 0; + data.open_rcv.keep = FALSE; + /* + * Indicate type of media (audio/video etc) becase some for + * supporting video over vieo, the port is obtained from other + * entity. + */ + data.open_rcv.media_type = media->type; + data.open_rcv.media_refid = media->refid; + if (cc_call_action(dcb_p->call_id, dcb_p->line, + CC_ACTION_OPEN_RCV, + &data) != CC_RC_SUCCESS) { + GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n", + dcb_p->line, dcb_p->call_id, fname); + gsmsdp_remove_media(dcb_p, media); + return (NULL); + } + + /* allocate port successful, save the port */ + + media->src_port = data.open_rcv.port; + + if(media_cap->type == SDP_MEDIA_APPLICATION) { config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port)); media->sctp_port = sctp_port; - } - - /* - * Setup the local soruce address. - */ - if (addr_type == CPR_IP_ADDR_IPV6) { - gsmsdp_get_local_source_v6_address(media); - } else if (addr_type == CPR_IP_ADDR_IPV4) { - gsmsdp_get_local_source_v4_address(media); - } else { - GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n", - dcb_p->line, dcb_p->call_id, fname); - gsmsdp_remove_media(dcb_p, media); - return (NULL); + } + + /* + * Setup the local soruce address. + */ + if (addr_type == CPR_IP_ADDR_IPV6) { + gsmsdp_get_local_source_v6_address(media); + } else if (addr_type == CPR_IP_ADDR_IPV4) { + gsmsdp_get_local_source_v4_address(media); + } else { + GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n", + dcb_p->line, dcb_p->call_id, fname); + gsmsdp_remove_media(dcb_p, media); + return (NULL); + } + } /* * Initialize the media transport for RTP or SRTP (or do not thing * and leave to the gsmsdp_update_local_sdp_media to set default) */ gsmsdp_init_sdp_media_transport(dcb_p, dcb_p->sdp->src_sdp, media); gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media, media->transport); - - gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction); - - /* - * wait until here to set ICE candidates as SDP is now initialized - */ - for (i=0; i<media->candidate_ct; i++) { - gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]); + if (media->support_direction != SDP_DIRECTION_INACTIVE) { + + gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction); + + /* + * wait until here to set ICE candidates as SDP is now initialized + */ + for (i=0; i<media->candidate_ct; i++) { + gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]); + } + + config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); + if (rtcpmux) { + gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE); + } + + + /* + * Since we are initiating an initial offer and opening a + * receive port, store initial media settings. + */ + media->previous_sdp.avt_payload_type = media->avt_payload_type; + media->previous_sdp.direction = media->direction; + media->previous_sdp.packetization_period = media->packetization_period; + media->previous_sdp.payload_type = media->payload; + media->previous_sdp.local_payload_type = media->payload; + break; } - config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux)); - if (rtcpmux) { - gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE); - } - - - /* - * Since we are initiating an initial offer and opening a - * receive port, store initial media settings. - */ - media->previous_sdp.avt_payload_type = media->avt_payload_type; - media->previous_sdp.direction = media->direction; - media->previous_sdp.packetization_period = media->packetization_period; - media->previous_sdp.payload_type = media->payload; - media->previous_sdp.local_payload_type = media->payload; - break; - default: /* Unsupported media type, not added */ GSM_DEBUG(DEB_L_C_F_PREFIX"media type %d is not supported\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media_cap->type); break; } return (media); } @@ -4692,17 +4774,17 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb * streams are added * * returns cc_causes_t * CC_CAUSE_OK - indicates success * CC_CAUSE_ERROR - indicates failure */ cc_causes_t gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data) + boolean audio, boolean video, boolean data, boolean offer) { static const char fname[] = "gsmsdp_create_local_sdp"; uint16_t level; const cc_media_cap_table_t *media_cap_tbl; const cc_media_cap_t *media_cap; cpr_ip_mode_e ip_mode; uint8_t cap_index; fsmdef_media_t *media; @@ -4724,17 +4806,17 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *d /* should not happen */ GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available\n", dcb_p->line, dcb_p->call_id, fname); return (CC_CAUSE_ERROR); } media_cap = &media_cap_tbl->cap[0]; level = 0; - for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) { + for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP-1; cap_index++) { /* Build local m lines based on m lines that were in the offered SDP */ media_enabled = TRUE; if (FALSE == audio && SDP_MEDIA_AUDIO == media_cap->type) { media_enabled = FALSE; } else if (FALSE == video && SDP_MEDIA_VIDEO == media_cap->type) { media_enabled = FALSE; } else if (FALSE == data && SDP_MEDIA_APPLICATION == media_cap->type) { @@ -4744,34 +4826,34 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *d /* * Add each enabled media line to the SDP */ if (media_enabled && ( media_cap->enabled || force_streams_enabled)) { level = level + 1; /* next level */ ip_mode = platform_get_ip_address_mode(); if (ip_mode >= CPR_IP_MODE_IPV6) { if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV6) + level, CPR_IP_ADDR_IPV6, offer) == NULL) { /* fail to add a media line, go back one level */ level = level - 1; } if (ip_mode == CPR_IP_MODE_DUAL) { level = level + 1; /* next level */ if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level, CPR_IP_ADDR_IPV4) == + level, CPR_IP_ADDR_IPV4, offer) == NULL) { /* fail to add a media line, go back one level */ level = level - 1; } } } else { if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, level, - CPR_IP_ADDR_IPV4) == NULL) { + CPR_IP_ADDR_IPV4, offer) == NULL) { /* fail to add a media line, go back one level */ level = level - 1; } } } /* next capability */ media_cap++; } @@ -5039,17 +5121,17 @@ gsmsdp_check_add_local_sdp_media (fsmdef num_m_lines = sdp_get_num_media_lines(src_sdp); level_to_use = num_m_lines + 1; } GSM_DEBUG(DEB_L_C_F_PREFIX"add media at level %d\n", DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level_to_use); /* add a new media */ media = gsmsdp_add_media_line(dcb_p, media_cap, cap_index, - level_to_use, ip_addr_type[i]); + level_to_use, ip_addr_type[i], FALSE); if (media != NULL) { /* successfully add a new media line */ if (hold) { /* this new media needs to be sent out with hold */ gsmsdp_set_local_hold_sdp(dcb_p, media); } added = TRUE; } else { @@ -5765,17 +5847,17 @@ gsmsdp_negotiate_answer_sdp (fsm_fcb_t * } if (status != CC_CAUSE_OK) { /* Error parsing SDP */ return status; } gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp); - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE); + status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE, TRUE); GSM_DEBUG(DEB_F_PREFIX"returns with %d\n",DEB_F_PREFIX_ARGS(GSM, fname), status); return (status); } /* @@ -5803,17 +5885,17 @@ gsmsdp_negotiate_offer_sdp (fsm_fcb_t *f status = gsmsdp_process_offer_sdp(fcb_p, msg_body, init); if (status != CC_CAUSE_OK) return status; /* * If a new error code has been added to sdp processing please make sure * the sip side is aware of it */ - status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE); + status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE, FALSE); return (status); } /* * gsmsdp_process_offer_sdp * * Description: @@ -5847,17 +5929,17 @@ gsmsdp_process_offer_sdp (fsm_fcb_t *fcb DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), init); if (num_sdp_bodies == 0) { /* * No remote SDP. So we will offer in our response and receive far end * answer in the ack. Only need to create local sdp if this is first offer * of a session. Otherwise, we will send what we have. */ if (init) { - if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE)) { + if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE, TRUE)) { return CC_CAUSE_ERROR; } } else { /* * Reset all media entries that we have to offer all capabilities */ (void)gsmsdp_update_local_sdp_media_capability(dcb_p, TRUE, FALSE); }
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c @@ -944,43 +944,41 @@ gsmsdp_check_answer_crypto_param (fsmdef * crypto_inst - pointer to crypto attribute instance number of the * selected crypto line * * Returns: * transport - sdp_transport_e for RTP or SRTP or invalid */ static sdp_transport_e gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, - fsmdef_media_t *media, uint16_t *crypto_inst) + fsmdef_media_t *media, uint16_t *crypto_inst, uint16 dest_level) { sdp_transport_e remote_transport; sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID; void *sdp_p = cc_sdp_p->dest_sdp; - uint16_t level; int sdpmode = 0; config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode)); - level = media->level; *crypto_inst = 0; - remote_transport = sdp_get_media_transport(sdp_p, level); + remote_transport = sdp_get_media_transport(sdp_p, dest_level); /* negotiate media transport */ switch (remote_transport) { case SDP_TRANSPORT_RTPAVP: /* Remote offers RTP for media transport, negotiated transport to RTP */ negotiated_transport = SDP_TRANSPORT_RTPAVP; break; case SDP_TRANSPORT_RTPSAVP: /* Remote offer SRTP for media transport */ if (((sip_regmgr_get_sec_level(dcb_p->line) == ENCRYPTED) && FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) || sdpmode) { /* The signalling with this line is encrypted, try to use SRTP */ - if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, level, crypto_inst)) { + if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, dest_level, crypto_inst)) { /* Found a suitable crypto line from the remote offer */ negotiated_transport = SDP_TRANSPORT_RTPSAVP; } } if (negotiated_transport == SDP_TRANSPORT_INVALID) { /* * Unable to find a suitable crypto or the signaling is @@ -1108,24 +1106,24 @@ gsmsdp_negotiate_answer_crypto (fsmdef_d * selected crypto line. * * Returns: * transport - sdp_transport_e for RTP or SRTP or invalid */ sdp_transport_e gsmsdp_negotiate_media_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, boolean offer, fsmdef_media_t *media, - uint16_t *crypto_inst) + uint16_t *crypto_inst, uint16 level) { sdp_transport_e transport; /* negotiate media transport based on offer or answer from the remote */ if (offer) { transport = gsmsdp_negotiate_offer_crypto(dcb_p, cc_sdp_p, media, - crypto_inst); + crypto_inst, level); } else { transport = gsmsdp_negotiate_answer_crypto(dcb_p, cc_sdp_p, media, crypto_inst); } return (transport); } /* @@ -1688,26 +1686,27 @@ gsmsdp_update_crypto_transmit_key (fsmde * Returns: * none */ void gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, fsmdef_media_t *media, uint16_t crypto_inst, - sdp_transport_e transport) + sdp_transport_e transport, + uint16 dest_level) { const char *fname = "gsmsdp_update_negotiated_transport"; sdp_srtp_crypto_suite_t crypto_suite; void *dest_sdp = cc_sdp_p->dest_sdp; vcm_crypto_algorithmID algorithmID; vcm_crypto_key_t key; uint16_t level; - level = media->level; + level = dest_level; /* * Also detect changes of the crypto parameters for Tx and Rx. * It is done here to avoid adding last crypto parameters for Tx and * Rx into the dcb structure since the parameters include key which * are rather long. This minimize the dcb's increasing. */ /* reset changes flags */ media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_TX_CHANGE |
--- a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h +++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h @@ -45,35 +45,35 @@ typedef enum constraints_ { static const gsmsdp_key_table_entry_t constraints_table[] = { {"OfferToReceiveAudio", OfferToReceiveAudio}, {"OfferToReceiveVideo", OfferToReceiveVideo}, {"VoiceActivityDetection", VoiceActivityDetection} }; cc_causes_t gsmsdp_create_local_sdp(fsmdef_dcb_t *dcb_p, boolean force_streams_enabled, - boolean audio, boolean video, boolean data); + boolean audio, boolean video, boolean data, boolean offer); void gsmsdp_create_options_sdp(cc_sdp_t **sdp_pp); void gsmsdp_reset_local_sdp_media(fsmdef_dcb_t *dcb, fsmdef_media_t *media, boolean hold); void gsmsdp_set_local_sdp_direction(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, sdp_direction_e direction); void gsmsdp_set_local_hold_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); void gsmsdp_set_local_resume_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media); cc_causes_t gsmsdp_negotiate_answer_sdp(fsm_fcb_t *fcb, cc_msgbody_info_t *msg_body); cc_causes_t gsmsdp_negotiate_offer_sdp(fsm_fcb_t *fcb, cc_msgbody_info_t *msg_body, boolean init); cc_causes_t gsmsdp_process_offer_sdp(fsm_fcb_t *fcb, cc_msgbody_info_t *msg_body, boolean init); cc_causes_t -gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, - boolean initial_offer, boolean offer, boolean notify_stream_added); +gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer, + boolean offer, boolean notify_stream_added, boolean create_answer); boolean gsmsdp_sdp_differs_from_previous_sdp(boolean rcv_only, fsmdef_media_t *media); cc_causes_t gsmsdp_encode_sdp(cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body); cc_causes_t gsmsdp_encode_sdp_and_update_version(fsmdef_dcb_t *dcb_p, cc_msgbody_info_t *msg_body); void gsmsdp_free(fsmdef_dcb_t *dcb_p); fsmdef_media_t *gsmsdp_find_audio_media(fsmdef_dcb_t *dcb_p); @@ -85,27 +85,29 @@ extern void gsmsdp_init_sdp_media_transp extern void gsmsdp_reset_sdp_media_transport(fsmdef_dcb_t *dcb, void *sdp, fsmdef_media_t *media, boolean hold); extern sdp_transport_e gsmsdp_negotiate_media_transport(fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, boolean offer, fsmdef_media_t *media, - uint16_t *inst_num); + uint16_t *inst_num, + uint16 level); extern void gsmsdp_update_local_sdp_media_transport(fsmdef_dcb_t *dcb_p, void *sdp_p, fsmdef_media_t *media, sdp_transport_e transport, boolean all); extern void gsmsdp_update_negotiated_transport(fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p, fsmdef_media_t *media, uint16_t crypto_inst, - sdp_transport_e transport); + sdp_transport_e transport, + uint16 level); extern void gsmsdp_update_crypto_transmit_key(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media, boolean offer, boolean initial_offer, sdp_direction_e direction); extern void gsmsdp_set_media_transport_for_option(void *sdp, uint16 level); extern boolean gsmsdp_is_crypto_ready(fsmdef_media_t *media, boolean rx); extern boolean gsmsdp_is_media_encrypted(fsmdef_dcb_t *dcb_p); @@ -127,11 +129,11 @@ boolean is_gsmsdp_media_ip_updated_to_la void gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, fsmdef_dcb_t * dcb, fsmdef_media_t *media); cc_causes_t gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p); cc_causes_t gsmsdp_configure_dtls_data_attributes(fsm_fcb_t *fcb_p); cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uint16_t *level); void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints); cc_causes_t gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data); - +fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e media_type); #endif
--- a/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c +++ b/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c @@ -13,18 +13,18 @@ * global media cap table for interaction between what platform * can do and the GSM-SDP module * AUDIO_1 is used for audio cannot be turned off * VIDEO_1 is used for video */ cc_media_cap_table_t g_media_table = { 1, { - {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_SENDRECV}, - {CC_VIDEO_1,SDP_MEDIA_VIDEO,FALSE,TRUE,SDP_DIRECTION_SENDRECV}, + {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, + {CC_VIDEO_1,SDP_MEDIA_VIDEO,TRUE,TRUE,SDP_DIRECTION_RECVONLY}, {CC_DATACHANNEL_1,SDP_MEDIA_APPLICATION,FALSE,TRUE,SDP_DIRECTION_SENDRECV}, } }; static boolean g_nativeVidSupported = FALSE; static boolean g_vidCapEnabled = FALSE; static boolean g_natve_txCap_enabled = FALSE;
--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h @@ -253,23 +253,28 @@ typedef enum { /* T.38 udp EC Types */ typedef enum { SDP_T38_UDP_REDUNDANCY, SDP_T38_UDP_FEC, SDP_T38_UDPEC_UNKNOWN, SDP_T38_MAX_UDPEC } sdp_t38_udpec_e; +/* Bitmaps for manipulating sdp_direction_e */ +typedef enum { + SDP_DIRECTION_FLAG_SEND=0x01, + SDP_DIRECTION_FLAG_RECV=0x02 +} sdp_direction_flag_e; /* Media flow direction */ typedef enum { - SDP_DIRECTION_INACTIVE, - SDP_DIRECTION_SENDONLY, - SDP_DIRECTION_RECVONLY, - SDP_DIRECTION_SENDRECV, + SDP_DIRECTION_INACTIVE = 0, + SDP_DIRECTION_SENDONLY = SDP_DIRECTION_FLAG_SEND, + SDP_DIRECTION_RECVONLY = SDP_DIRECTION_FLAG_RECV, + SDP_DIRECTION_SENDRECV = SDP_DIRECTION_FLAG_SEND | SDP_DIRECTION_FLAG_RECV, SDP_MAX_QOS_DIRECTIONS } sdp_direction_e; #define SDP_DIRECTION_PRINT(arg) \ (((sdp_direction_e)(arg)) == SDP_DIRECTION_INACTIVE ? "SDP_DIRECTION_INACTIVE " : \ ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDONLY ? "SDP_DIRECTION_SENDONLY": \ ((sdp_direction_e)(arg)) == SDP_DIRECTION_RECVONLY ? "SDP_DIRECTION_RECVONLY ": \ ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDRECV ? " SDP_DIRECTION_SENDRECV": "SDP_MAX_QOS_DIRECTIONS")
--- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -66,16 +66,51 @@ static const std::string strSampleSdpAud static const std::string strSampleCandidate = "a=candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host\r\n"; static const std::string strSampleMid = ""; static const unsigned short nSamplelevel = 2; +enum sdpTestFlags +{ + SHOULD_SEND_AUDIO = (1<<0), + SHOULD_RECV_AUDIO = (1<<1), + SHOULD_INACTIVE_AUDIO = (1<<2), + SHOULD_REJECT_AUDIO = (1<<3), + SHOULD_SEND_VIDEO = (1<<4), + SHOULD_RECV_VIDEO = (1<<5), + SHOULD_INACTIVE_VIDEO = (1<<6), + SHOULD_REJECT_VIDEO = (1<<7), + + SHOULD_SENDRECV_AUDIO = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO, + SHOULD_SENDRECV_VIDEO = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO, + SHOULD_SENDRECV_AV = SHOULD_SENDRECV_AUDIO | SHOULD_SENDRECV_VIDEO, + AUDIO_FLAGS = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO + | SHOULD_INACTIVE_AUDIO | SHOULD_REJECT_AUDIO, + VIDEO_FLAGS = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO + | SHOULD_INACTIVE_VIDEO | SHOULD_REJECT_VIDEO +}; + +enum offerAnswerFlags +{ + OFFER_NONE = 0, // Sugar to make function calls clearer. + OFFER_AUDIO = (1<<0), + OFFER_VIDEO = (1<<1), + // Leaving some room here for other media types + ANSWER_NONE = 0, // Sugar to make function calls clearer. + ANSWER_AUDIO = (1<<8), + ANSWER_VIDEO = (1<<9), + + OFFER_AV = OFFER_AUDIO | OFFER_VIDEO, + ANSWER_AV = ANSWER_AUDIO | ANSWER_VIDEO +}; + + class TestObserver : public IPeerConnectionObserver { public: enum Action { OFFER, ANSWER }; @@ -475,17 +510,18 @@ class SignalingAgent { // Shutdown is synchronous evidently. // ASSERT_TRUE(pObserver->WaitForObserverCall()); // ASSERT_EQ(pc->sipcc_state(), sipcc::PeerConnectionInterface::kIdle); } char* offer() const { return offer_; } char* answer() const { return answer_; } - void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) { + void CreateOffer(sipcc::MediaConstraints& constraints, + uint32_t offerFlags, uint32_t sdpCheck) { // Create a media stream as if it came from GUM Fake_AudioStreamSource *audio_stream = new Fake_AudioStreamSource(); nsresult ret; test_utils->sts_target()->Dispatch( WrapRunnableRet(audio_stream, &Fake_MediaStream::Start, &ret), @@ -494,91 +530,91 @@ class SignalingAgent { ASSERT_TRUE(NS_SUCCEEDED(ret)); // store in object to be used by RemoveStream nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream(audio_stream); domMediaStream_ = domMediaStream; uint32_t aHintContents = 0; - if (audio) { + if (offerFlags & OFFER_AUDIO) { aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO; } - if (video) { + if (offerFlags & OFFER_VIDEO) { aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO; } - PR_ASSERT(aHintContents); - domMediaStream->SetHintContents(aHintContents); pc->AddStream(domMediaStream); domMediaStream_ = domMediaStream; // Now call CreateOffer as JS would pObserver->state = TestObserver::stateNoResponse; ASSERT_EQ(pc->CreateOffer(constraints), NS_OK); ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout); - SDPSanityCheck(pObserver->lastString, audio, video, true); + SDPSanityCheck(pObserver->lastString, sdpCheck, true); offer_ = pObserver->lastString; } void CreateOfferExpectError(sipcc::MediaConstraints& constraints) { ASSERT_EQ(pc->CreateOffer(constraints), NS_OK); ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateError, kDefaultTimeout); } - void CreateAnswer(sipcc::MediaConstraints& constraints, bool audio, bool video) { +void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer, + uint32_t offerAnswerFlags, uint32_t sdpCheck) { // Create a media stream as if it came from GUM nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream(); uint32_t aHintContents = 0; - if (audio) { + if (offerAnswerFlags & ANSWER_AUDIO) { aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO; } - if (video) { + if (offerAnswerFlags & ANSWER_VIDEO) { aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO; } - PR_ASSERT(aHintContents); - domMediaStream->SetHintContents(aHintContents); pc->AddStream(domMediaStream); + // Decide if streams are disabled for offer or answer + // then perform SDP checking based on which stream disabled + pObserver->state = TestObserver::stateNoResponse; ASSERT_EQ(pc->CreateAnswer(constraints), NS_OK); ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout); - SDPSanityCheck(pObserver->lastString, audio, video, false); + SDPSanityCheck(pObserver->lastString, sdpCheck, false); + answer_ = pObserver->lastString; } - void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) { - - uint32_t aHintContents = 0; + // At present, we use the hints field in a stream to find and + // remove it. This only works if the specified hints flags are + // unique among all streams in the PeerConnection. This is not + // generally true, and will need significant revision once + // multiple streams are supported. + void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, + uint32_t hints, uint32_t sdpCheck) { - if (!audio) { - aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO; - } - if (!video) { - aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO; - } + domMediaStream_->SetHintContents(hints); - domMediaStream_->SetHintContents(aHintContents); - + // This currently "removes" a stream that has the same audio/video + // hints as were passed in. // When complete RemoveStream will remove and entire stream and its tracks // not just disable a track as this is currently doing pc->RemoveStream(domMediaStream_); // Now call CreateOffer as JS would pObserver->state = TestObserver::stateNoResponse; ASSERT_EQ(pc->CreateOffer(constraints), NS_OK); ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout); - SDPSanityCheck(pObserver->lastString, audio, video, true); + SDPSanityCheck(pObserver->lastString, sdpCheck, true); offer_ = pObserver->lastString; } void SetRemote(TestObserver::Action action, std::string remote) { pObserver->state = TestObserver::stateNoResponse; ASSERT_EQ(pc->SetRemoteDescription(action, remote.c_str()), NS_OK); ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout); } @@ -629,319 +665,538 @@ class SignalingAgent { public: mozilla::RefPtr<sipcc::PeerConnectionImpl> pc; nsRefPtr<TestObserver> pObserver; char* offer_; char* answer_; nsRefPtr<nsDOMMediaStream> domMediaStream_; - private: - void SDPSanityCheck(std::string sdp, bool shouldHaveAudio, bool shouldHaveVideo, bool offer) + void SDPSanityCheck(std::string sdp, uint32_t flags, bool offer) { ASSERT_NE(sdp.find("v=0"), std::string::npos); ASSERT_NE(sdp.find("c=IN IP4"), std::string::npos); ASSERT_NE(sdp.find("a=fingerprint:sha-256"), std::string::npos); - if (shouldHaveAudio) - { - if (offer) - ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos); + cout << "SDPSanityCheck flags = " << std::hex << std::showbase + << flags << std::dec + << ((flags & SHOULD_SEND_AUDIO)?" SHOULD_SEND_AUDIO":"") + << ((flags & SHOULD_RECV_AUDIO)?" SHOULD_RECV_AUDIO":"") + << ((flags & SHOULD_INACTIVE_AUDIO)?" SHOULD_INACTIVE_AUDIO":"") + << ((flags & SHOULD_REJECT_AUDIO)?" SHOULD_REJECT_AUDIO":"") + << ((flags & SHOULD_SEND_VIDEO)?" SHOULD_SEND_VIDEO":"") + << ((flags & SHOULD_RECV_VIDEO)?" SHOULD_RECV_VIDEO":"") + << ((flags & SHOULD_INACTIVE_VIDEO)?" SHOULD_INACTIVE_VIDEO":"") + << ((flags & SHOULD_REJECT_VIDEO)?" SHOULD_REJECT_VIDEO":"") + << endl; - - // after negotiation we are left with one codec - ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + if ((flags & AUDIO_FLAGS) && offer) { + ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos); } - if (shouldHaveVideo) - { - ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos); + switch(flags & AUDIO_FLAGS) { + case 0: + ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + break; + case SHOULD_SEND_AUDIO: + ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendonly"), std::string::npos); + break; + case SHOULD_RECV_AUDIO: + ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=recvonly"), std::string::npos); + break; + case SHOULD_SENDRECV_AUDIO: + ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendrecv"), std::string::npos); + break; + case SHOULD_INACTIVE_AUDIO: + ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=inactive"), std::string::npos); + break; + case SHOULD_REJECT_AUDIO: + ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos); + ASSERT_NE(sdp.find("m=audio 0 "), std::string::npos); + break; + default: + ASSERT_FALSE("Missing case in switch statement"); + } + + switch(flags & VIDEO_FLAGS) { + case 0: + ASSERT_EQ(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos); + break; + case SHOULD_SEND_VIDEO: + ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendonly"), + std::string::npos); + break; + case SHOULD_RECV_VIDEO: + ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=recvonly"), + std::string::npos); + break; + case SHOULD_SENDRECV_VIDEO: + ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendrecv"), + std::string::npos); + break; + case SHOULD_INACTIVE_VIDEO: + ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=inactive"), + std::string::npos); + break; + case SHOULD_REJECT_VIDEO: + ASSERT_NE(sdp.find("m=video 0 "), std::string::npos); + break; + default: + ASSERT_FALSE("Missing case in switch statement"); } } }; class SignalingEnvironment : public ::testing::Environment { public: void TearDown() { sipcc::PeerConnectionImpl::Shutdown(); } }; class SignalingTest : public ::testing::Test { public: - void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) { - a1_.CreateOffer(constraints, audio, video); + void CreateOffer(sipcc::MediaConstraints& constraints, + uint32_t offerFlags, uint32_t sdpCheck) { + a1_.CreateOffer(constraints, offerFlags, sdpCheck); } - void CreateSetOffer(sipcc::MediaConstraints& constraints) { - a1_.CreateOffer(constraints, true, true); + void CreateSetOffer(sipcc::MediaConstraints& constraints, uint32_t sdpCheck) { + a1_.CreateOffer(constraints, OFFER_AV, sdpCheck); a1_.SetLocal(TestObserver::OFFER, a1_.offer()); } - void OfferAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints, - bool audio, bool video, bool finishAfterAnswer) { - a1_.CreateOffer(aconstraints, audio, video); + void OfferAnswer(sipcc::MediaConstraints& aconstraints, + sipcc::MediaConstraints& bconstraints, + uint32_t offerAnswerFlags, + bool finishAfterAnswer, uint32_t offerSdpCheck, + uint32_t answerSdpCheck) { + a1_.CreateOffer(aconstraints, offerAnswerFlags, offerSdpCheck); a1_.SetLocal(TestObserver::OFFER, a1_.offer()); a2_.SetRemote(TestObserver::OFFER, a1_.offer()); - a2_.CreateAnswer(bconstraints, audio, video); + a2_.CreateAnswer(bconstraints, a1_.offer(), + offerAnswerFlags, answerSdpCheck); if(true == finishAfterAnswer) { a2_.SetLocal(TestObserver::ANSWER, a2_.answer()); a1_.SetRemote(TestObserver::ANSWER, a2_.answer()); ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); } } - void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) { - a1_.CreateOffer(aconstraints, true, true); + void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints, + sipcc::MediaConstraints& bconstraints, + uint32_t offerSdpCheck, uint32_t answerSdpCheck) { + a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck); a1_.SetLocal(TestObserver::OFFER, a1_.offer()); a2_.SetRemote(TestObserver::OFFER, a1_.offer()); - a2_.CreateAnswer(bconstraints, true, true); + a2_.CreateAnswer(bconstraints, a1_.offer(), OFFER_AV | ANSWER_AV, + answerSdpCheck); a2_.SetLocal(TestObserver::ANSWER, a2_.answer()); ParsedSDP sdpWrapper(a2_.answer()); sdpWrapper.ReplaceLine("m=audio", "m=audio 65375 RTP/SAVPF 109 8 101\r\n"); sdpWrapper.AddLine("a=rtpmap:8 PCMA/8000\r\n"); cout << "Modified SDP " << sdpWrapper.getSdp() << endl; a1_.SetRemote(TestObserver::ANSWER, sdpWrapper.getSdp()); ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); } - void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) { - a1_.CreateOffer(aconstraints, true, true); + void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints, + sipcc::MediaConstraints& bconstraints, + uint32_t offerSdpCheck, uint32_t answerSdpCheck) { + a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck); a1_.SetLocal(TestObserver::OFFER, a1_.offer()); ParsedSDP a1_offer(a1_.offer()); a2_.SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_); - a2_.CreateAnswer(bconstraints, true, true); + a2_.CreateAnswer(bconstraints, a1_offer.sdp_without_ice_, + OFFER_AV|ANSWER_AV, answerSdpCheck); a2_.SetLocal(TestObserver::ANSWER, a2_.answer()); ParsedSDP a2_answer(a2_.answer()); a1_.SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_); // Now set the trickle ICE candidates a1_.DoTrickleIce(a2_answer); a2_.DoTrickleIce(a1_offer); ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout); ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout); } - void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) { + void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, + uint32_t hints, uint32_t sdpCheck) { sipcc::MediaConstraints aconstraints; aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - a1_.CreateOffer(aconstraints, true, true); - a1_.CreateOfferRemoveStream(constraints, audio, video); - } - - void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints) { - a1_.CreateOffer(constraints, true, false); + a1_.CreateOffer(aconstraints, OFFER_AV, SHOULD_SENDRECV_AV ); + a1_.CreateOfferRemoveStream(constraints, hints, sdpCheck); } - void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints) { - a1_.CreateOffer(constraints, true, true); - a1_.CreateOfferRemoveStream(constraints, false, true); + void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints, + uint32_t sdpCheck) { + a1_.CreateOffer(constraints, OFFER_AUDIO, sdpCheck); } - void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints, const char * candidate, const char * mid, unsigned short level) { - a1_.CreateOffer(constraints, true, true); + void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints, + const char * candidate, const char * mid, + unsigned short level, uint32_t sdpCheck) { + a1_.CreateOffer(constraints, OFFER_AV, sdpCheck); a1_.AddIceCandidate(candidate, mid, level); } protected: SignalingAgent a1_; // Canonically "caller" SignalingAgent a2_; // Canonically "callee" }; TEST_F(SignalingTest, JustInit) { } TEST_F(SignalingTest, CreateSetOffer) { sipcc::MediaConstraints constraints; - CreateSetOffer(constraints); + CreateSetOffer(constraints, SHOULD_SENDRECV_AV); } TEST_F(SignalingTest, CreateOfferAudioVideoConstraintUndefined) { sipcc::MediaConstraints constraints; - CreateOffer(constraints, true, true); + CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV); } TEST_F(SignalingTest, CreateOfferNoVideoStream) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", true, false); constraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - CreateOffer(constraints, true, false); + CreateOffer(constraints, OFFER_AUDIO, + SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO); } TEST_F(SignalingTest, CreateOfferNoAudioStream) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", true, false); constraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - CreateOffer(constraints, false, true); + CreateOffer(constraints, OFFER_VIDEO, + SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO); } TEST_F(SignalingTest, CreateOfferDontReceiveAudio) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", false, false); constraints.setBooleanConstraint("OfferToReceiveVideo", true, false); constraints.setBooleanConstraint("VoiceActivityDetection", true, true); - CreateOffer(constraints, true, true); + CreateOffer(constraints, OFFER_AV, + SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO); } TEST_F(SignalingTest, CreateOfferDontReceiveVideo) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", true, false); constraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - CreateOffer(constraints, true, true); + CreateOffer(constraints, OFFER_AV, + SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO); } TEST_F(SignalingTest, CreateOfferRemoveAudioStream) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", true, false); constraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - CreateOfferRemoveStream(constraints, false, true); + CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO, + SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO); } TEST_F(SignalingTest, CreateOfferDontReceiveAudioRemoveAudioStream) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", false, false); constraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - CreateOfferRemoveStream(constraints, false, true); + CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO, + SHOULD_SENDRECV_VIDEO); } TEST_F(SignalingTest, CreateOfferDontReceiveVideoRemoveVideoStream) { sipcc::MediaConstraints constraints; constraints.setBooleanConstraint("OfferToReceiveAudio", true, false); constraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - CreateOfferRemoveStream(constraints, true, false); + CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_VIDEO, + SHOULD_SENDRECV_AUDIO); +} + +TEST_F(SignalingTest, OfferAnswerNothingDisabled) +{ + sipcc::MediaConstraints constraints; + OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, false, + SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV); +} + +TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnOffer) +{ + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV, + false, SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO, + SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO); } -TEST_F(SignalingTest, OfferAnswerDontReceiveAudio) +TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnOffer) { - sipcc::MediaConstraints aconstraints; - aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false); - aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - sipcc::MediaConstraints bconstraints; - bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - OfferAnswer(aconstraints, bconstraints, true, true, false); + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV, + false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO, + SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO); } -TEST_F(SignalingTest, OfferAnswerDontReceiveVideo) +TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnAnswer) { - sipcc::MediaConstraints aconstraints; - aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - sipcc::MediaConstraints bconstraints; - bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - OfferAnswer(aconstraints, bconstraints, true, true, false); + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV, + false, SHOULD_SENDRECV_AV, + SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO); } TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnAnswer) { - sipcc::MediaConstraints aconstraints; - aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - sipcc::MediaConstraints bconstraints; - bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - OfferAnswer(aconstraints, bconstraints, true, true, false); + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV, + false, SHOULD_SENDRECV_AV, + SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO); +} + +TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOffer) +{ + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV, + false, SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO, + SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO); } -TEST_F(SignalingTest, OfferAnswerDontSendReceiveVideoNoVideoStream) +TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOffer) { - sipcc::MediaConstraints aconstraints; - aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - sipcc::MediaConstraints bconstraints; - bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); - bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); - OfferAnswer(aconstraints, bconstraints, true, false, false); + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV, + false, SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO, + SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO); +} + +TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswer) +{ + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO, + false, SHOULD_SENDRECV_AV, + SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO); } -TEST_F(SignalingTest, OfferAnswerDontSendReceiveAudioNoAudioStream) +TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswer) { - sipcc::MediaConstraints aconstraints; - aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false); - aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - sipcc::MediaConstraints bconstraints; - bconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false); - bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); - OfferAnswer(aconstraints, bconstraints, false, true, false); + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO, + false, SHOULD_SENDRECV_AV, + SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO); +} + +TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerDontReceiveVideoOnAnswer) +{ + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false); + OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO, + false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO ); } -TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamDontReceiveVideo) +TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerDontReceiveAudioOnAnswer) +{ + sipcc::MediaConstraints offerconstraints; + offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false); + offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false); + sipcc::MediaConstraints answerconstraints; + answerconstraints.setBooleanConstraint("OfferToReceiveAud