author | Carsten "Tomcat" Book <cbook@mozilla.com> |
Wed, 23 Oct 2013 15:03:32 +0200 | |
changeset 165613 | d91823b449d10871c3504247adf4b99907f4ac3e |
parent 165612 | ff5a19df4bed1bbb2c515de7d0bd388dcdb4b623 (current diff) |
parent 165602 | 8803e8c0ee3efe4c0c07be612ce51c1d274b7c96 (diff) |
child 165614 | 2d8cdd7baa58bfab0b5cd805e555f4bdb26a4c9b |
push id | 3066 |
push user | akeybl@mozilla.com |
push date | Mon, 09 Dec 2013 19:58:46 +0000 |
treeherder | mozilla-beta@a31a0dce83aa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
accessible/src/base/RoleAsserts.cpp | file | annotate | diff | comparison | revisions |
--- a/CLOBBER +++ b/CLOBBER @@ -13,9 +13,9 @@ # | | # O <-- Clobber O <-- Clobber # # Note: The description below will be part of the error message shown to users. # # Modifying this file will now automatically clobber the buildbot machines \o/ # -Bug 926091 says hello to bug 924992 by touching webidl +Bug 918207 needed a clobber on every platform because we can't have nice things
--- a/accessible/src/atk/AccessibleWrap.cpp +++ b/accessible/src/atk/AccessibleWrap.cpp @@ -866,66 +866,58 @@ refStateSetCB(AtkObject *aAtkObj) } // Map states TranslateStates(accWrap->State(), state_set); return state_set; } +static void +UpdateAtkRelation(RelationType aType, Accessible* aAcc, + AtkRelationType aAtkType, AtkRelationSet* aAtkSet) +{ + if (aAtkType == ATK_RELATION_NULL) + return; + + AtkRelation* atkRelation = + atk_relation_set_get_relation_by_type(aAtkSet, aAtkType); + if (atkRelation) + atk_relation_set_remove(aAtkSet, atkRelation); + + Relation rel(aAcc->RelationByType(aType)); + nsTArray<AtkObject*> targets; + Accessible* tempAcc = nullptr; + while ((tempAcc = rel.Next())) + targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc)); + + if (targets.Length()) { + atkRelation = atk_relation_new(targets.Elements(), + targets.Length(), aAtkType); + atk_relation_set_add(aAtkSet, atkRelation); + g_object_unref(atkRelation); + } +} + AtkRelationSet * refRelationSetCB(AtkObject *aAtkObj) { AtkRelationSet* relation_set = ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj); AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); if (!accWrap) return relation_set; - // Keep in sync with AtkRelationType enum. - static const RelationType relationTypes[] = { - RelationType::CONTROLLED_BY, - RelationType::CONTROLLER_FOR, - RelationType::LABEL_FOR, - RelationType::LABELLED_BY, - RelationType::MEMBER_OF, - RelationType::NODE_CHILD_OF, - RelationType::FLOWS_TO, - RelationType::FLOWS_FROM, - RelationType::SUBWINDOW_OF, - RelationType::EMBEDS, - RelationType::EMBEDDED_BY, - RelationType::POPUP_FOR, - RelationType::PARENT_WINDOW_OF, - RelationType::DESCRIBED_BY, - RelationType::DESCRIPTION_FOR, - RelationType::NODE_PARENT_OF - }; +#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \ + UpdateAtkRelation(RelationType::geckoType, accWrap, atkType, relation_set); - for (uint32_t i = 0; i < ArrayLength(relationTypes); i++) { - // Shift to 1 to skip ATK_RELATION_NULL. - AtkRelationType atkType = static_cast<AtkRelationType>(i + 1); - AtkRelation* atkRelation = - atk_relation_set_get_relation_by_type(relation_set, atkType); - if (atkRelation) - atk_relation_set_remove(relation_set, atkRelation); +#include "RelationTypeMap.h" - Relation rel(accWrap->RelationByType(relationTypes[i])); - nsTArray<AtkObject*> targets; - Accessible* tempAcc = nullptr; - while ((tempAcc = rel.Next())) - targets.AppendElement(AccessibleWrap::GetAtkObject(tempAcc)); - - if (targets.Length()) { - atkRelation = atk_relation_new(targets.Elements(), targets.Length(), atkType); - atk_relation_set_add(relation_set, atkRelation); - g_object_unref(atkRelation); - } - } +#undef RELATIONTYPE return relation_set; } // Check if aAtkObj is a valid MaiAtkObject, and return the AccessibleWrap // for it. AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj)
rename from accessible/src/base/RoleAsserts.cpp rename to accessible/src/base/Asserts.cpp --- a/accessible/src/base/RoleAsserts.cpp +++ b/accessible/src/base/Asserts.cpp @@ -1,17 +1,26 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsIAccessibleRelation.h" #include "nsIAccessibleRole.h" +#include "RelationType.h" #include "Role.h" using namespace mozilla::a11y; #define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role, nameRule) \ static_assert(static_cast<uint32_t>(roles::geckoRole) \ == static_cast<uint32_t>(nsIAccessibleRole::ROLE_ ## geckoRole), \ "internal and xpcom roles differ!"); #include "RoleMap.h" #undef ROLE + +#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \ + static_assert(static_cast<uint32_t>(RelationType::geckoType) \ + == static_cast<uint32_t>(nsIAccessibleRelation::RELATION_ ## geckoType), \ + "internal and xpcom relations differ!"); +#include "RelationTypeMap.h" +#undef RELATIONTYPE
new file mode 100644 --- /dev/null +++ b/accessible/src/base/RelationTypeMap.h @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Usage: declare the macro RELATIONTYPE()with the following arguments: + * RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) + */ + +RELATIONTYPE(LABELLED_BY, + "labelled by", + ATK_RELATION_LABELLED_BY, + NAVRELATION_LABELLED_BY, + IA2_RELATION_LABELLED_BY) + +RELATIONTYPE(LABEL_FOR, + "label for", + ATK_RELATION_LABEL_FOR, + NAVRELATION_LABEL_FOR, + IA2_RELATION_LABEL_FOR) + +RELATIONTYPE(DESCRIBED_BY, + "described by", + ATK_RELATION_DESCRIBED_BY, + NAVRELATION_DESCRIBED_BY, + IA2_RELATION_DESCRIBED_BY) + +RELATIONTYPE(DESCRIPTION_FOR, + "description for", + ATK_RELATION_DESCRIPTION_FOR, + NAVRELATION_DESCRIPTION_FOR, + IA2_RELATION_DESCRIPTION_FOR) + +RELATIONTYPE(NODE_CHILD_OF, + "node child of", + ATK_RELATION_NODE_CHILD_OF, + NAVRELATION_NODE_CHILD_OF, + IA2_RELATION_NODE_CHILD_OF) + +RELATIONTYPE(NODE_PARENT_OF, + "node parent of", + ATK_RELATION_NODE_PARENT_OF, + NAVRELATION_NODE_PARENT_OF, + IA2_RELATION_NODE_PARENT_OF) + +RELATIONTYPE(CONTROLLED_BY, + "controlled by", + ATK_RELATION_CONTROLLED_BY, + NAVRELATION_CONTROLLED_BY, + IA2_RELATION_CONTROLLED_BY) + +RELATIONTYPE(CONTROLLER_FOR, + "controller for", + ATK_RELATION_CONTROLLER_FOR, + NAVRELATION_CONTROLLER_FOR, + IA2_RELATION_CONTROLLER_FOR) + +RELATIONTYPE(FLOWS_TO, + "flows to", + ATK_RELATION_FLOWS_TO, + NAVRELATION_FLOWS_TO, + IA2_RELATION_FLOWS_TO) + +RELATIONTYPE(FLOWS_FROM, + "flows from", + ATK_RELATION_FLOWS_FROM, + NAVRELATION_FLOWS_FROM, + IA2_RELATION_FLOWS_FROM) + +RELATIONTYPE(MEMBER_OF, + "member of", + ATK_RELATION_MEMBER_OF, + NAVRELATION_MEMBER_OF, + IA2_RELATION_MEMBER_OF) + +RELATIONTYPE(SUBWINDOW_OF, + "subwindow of", + ATK_RELATION_SUBWINDOW_OF, + NAVRELATION_SUBWINDOW_OF, + IA2_RELATION_SUBWINDOW_OF) + +RELATIONTYPE(EMBEDS, + "embeds", + ATK_RELATION_EMBEDS, + NAVRELATION_EMBEDS, + IA2_RELATION_EMBEDS) + +RELATIONTYPE(EMBEDDED_BY, + "embedded by", + ATK_RELATION_EMBEDDED_BY, + NAVRELATION_EMBEDDED_BY, + IA2_RELATION_EMBEDDED_BY) + +RELATIONTYPE(POPUP_FOR, + "popup for", + ATK_RELATION_POPUP_FOR, + NAVRELATION_POPUP_FOR, + IA2_RELATION_POPUP_FOR) + +RELATIONTYPE(PARENT_WINDOW_OF, + "parent window of", + ATK_RELATION_PARENT_WINDOW_OF, + NAVRELATION_PARENT_WINDOW_OF, + IA2_RELATION_PARENT_WINDOW_OF) + +RELATIONTYPE(DEFAULT_BUTTON, + "default button", + ATK_RELATION_NULL, + NAVRELATION_DEFAULT_BUTTON, + IA2_RELATION_NULL)
--- a/accessible/src/base/moz.build +++ b/accessible/src/base/moz.build @@ -32,29 +32,29 @@ if CONFIG['MOZ_DEBUG']: CPP_SOURCES += [ 'AccCollector.cpp', 'AccEvent.cpp', 'AccGroupInfo.cpp', 'AccIterator.cpp', 'ARIAMap.cpp', 'ARIAStateMap.cpp', + 'Asserts.cpp', 'DocManager.cpp', 'EventQueue.cpp', 'Filters.cpp', 'FocusManager.cpp', 'NotificationController.cpp', 'nsAccessibilityService.cpp', 'nsAccessiblePivot.cpp', 'nsAccessNode.cpp', 'nsAccUtils.cpp', 'nsCoreUtils.cpp', 'nsEventShell.cpp', 'nsTextEquivUtils.cpp', - 'RoleAsserts.cpp', 'SelectionManager.cpp', 'StyleInfo.cpp', 'TextAttrs.cpp', 'TextUpdater.cpp', 'TreeWalker.cpp', ] if a11y_log:
--- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -708,23 +708,32 @@ nsAccessibilityService::GetStringEventTy return NS_OK; } // nsIAccessibleRetrieval::getStringRelationType() NS_IMETHODIMP nsAccessibilityService::GetStringRelationType(uint32_t aRelationType, nsAString& aString) { - if (aRelationType >= ArrayLength(kRelationTypeNames)) { - aString.AssignLiteral("unknown"); + NS_ENSURE_ARG(aRelationType <= static_cast<uint32_t>(RelationType::LAST)); + +#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \ + case RelationType::geckoType: \ + aString.AssignLiteral(geckoTypeName); \ return NS_OK; + + RelationType relationType = static_cast<RelationType>(aRelationType); + switch (relationType) { +#include "RelationTypeMap.h" + default: + aString.AssignLiteral("unknown"); + return NS_OK; } - CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString); - return NS_OK; +#undef RELATIONTYPE } NS_IMETHODIMP nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode, nsIAccessible** aAccessible) { NS_ENSURE_ARG_POINTER(aAccessible); *aAccessible = nullptr;
--- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -327,34 +327,10 @@ static const char kEventTypeNames[][40] "hypertext link selected", // EVENT_HYPERTEXT_LINK_SELECTED "hyperlink start index changed", // EVENT_HYPERLINK_START_INDEX_CHANGED "hypertext changed", // EVENT_HYPERTEXT_CHANGED "hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED "object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED "virtual cursor changed" // EVENT_VIRTUALCURSOR_CHANGED }; -/** - * Map nsIAccessibleRelation constants to strings. Used by - * nsIAccessibleRetrieval::getStringRelationType() method. - */ -static const char kRelationTypeNames[][20] = { - "labelled by", // RELATION_LABELLED_BY - "label for", // RELATION_LABEL_FOR - "described by", // RELATION_DESCRIBED_BY - "description for", // RELATION_DESCRIPTION_FOR - "node child of", // RELATION_NODE_CHILD_OF - "node parent of", // RELATION_NODE_PARENT_OF - "controlled by", // RELATION_CONTROLLED_BY - "controller for", // RELATION_CONTROLLER_FOR - "flows to", // RELATION_FLOWS_TO - "flows from", // RELATION_FLOWS_FROM - "member of", // RELATION_MEMBER_OF - "subwindow of", // RELATION_SUBWINDOW_OF - "embeds", // RELATION_EMBEDS - "embedded by", // RELATION_EMBEDDED_BY - "popup for", // RELATION_POPUP_FOR - "parent window of", // RELATION_PARENT_WINDOW_OF - "default button" // RELATION_DEFAULT_BUTTON -}; - #endif /* __nsIAccessibilityService_h__ */
--- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -25,16 +25,17 @@ #include "TableAccessible.h" #include "TableCellAccessible.h" #include "TreeWalker.h" #include "nsIDOMElement.h" #include "nsIDOMDocument.h" #include "nsIDOMNodeFilter.h" #include "nsIDOMHTMLElement.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMTreeWalker.h" #include "nsIDOMXULButtonElement.h" #include "nsIDOMXULDocument.h" #include "nsIDOMXULElement.h" #include "nsIDOMXULLabelElement.h" #include "nsIDOMXULSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" #include "nsPIDOMWindow.h"
--- a/accessible/src/windows/ia2/ia2Accessible.cpp +++ b/accessible/src/windows/ia2/ia2Accessible.cpp @@ -55,18 +55,21 @@ ia2Accessible::get_nRelations(long* aNRe if (!aNRelations) return E_INVALIDARG; *aNRelations = 0; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) { - Relation rel = acc->RelationByType(sRelationTypesForIA2[idx]); + for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { + if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) + continue; + + Relation rel = acc->RelationByType(sRelationTypePairs[idx].first); if (rel.Next()) (*aNRelations)++; } return S_OK; A11Y_TRYBLOCK_END } @@ -80,18 +83,21 @@ ia2Accessible::get_relation(long aRelati return E_INVALIDARG; *aRelation = nullptr; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; long relIdx = 0; - for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) { - RelationType relationType = sRelationTypesForIA2[idx]; + for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs); idx++) { + if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) + continue; + + RelationType relationType = sRelationTypePairs[idx].first; Relation rel = acc->RelationByType(relationType); nsRefPtr<ia2AccessibleRelation> ia2Relation = new ia2AccessibleRelation(relationType, &rel); if (ia2Relation->HasTargets()) { if (relIdx == aRelationIndex) { ia2Relation.forget(aRelation); return S_OK; } @@ -115,19 +121,22 @@ ia2Accessible::get_relations(long aMaxRe if (!aRelation || !aNRelations) return E_INVALIDARG; *aNRelations = 0; AccessibleWrap* acc = static_cast<AccessibleWrap*>(this); if (acc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2) && + for (uint32_t idx = 0; idx < ArrayLength(sRelationTypePairs) && *aNRelations < aMaxRelations; idx++) { - RelationType relationType = sRelationTypesForIA2[idx]; + if (sRelationTypePairs[idx].second == IA2_RELATION_NULL) + continue; + + RelationType relationType = sRelationTypePairs[idx].first; Relation rel = acc->RelationByType(relationType); nsRefPtr<ia2AccessibleRelation> ia2Rel = new ia2AccessibleRelation(relationType, &rel); if (ia2Rel->HasTargets()) { ia2Rel.forget(aRelation + (*aNRelations)); (*aNRelations)++; } }
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp +++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp @@ -28,74 +28,32 @@ ia2AccessibleRelation::ia2AccessibleRela IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleRelation) IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleRelation) IMPL_IUNKNOWN_QUERY_IFACE(IUnknown) IMPL_IUNKNOWN_QUERY_TAIL // IAccessibleRelation STDMETHODIMP -ia2AccessibleRelation::get_relationType(BSTR *aRelationType) +ia2AccessibleRelation::get_relationType(BSTR* aRelationType) { A11Y_TRYBLOCK_BEGIN if (!aRelationType) return E_INVALIDARG; *aRelationType = nullptr; +#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \ + case RelationType::geckoType: \ + *aRelationType = ::SysAllocString(ia2Type); \ + break; + switch (mType) { - case RelationType::CONTROLLED_BY: - *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY); - break; - case RelationType::CONTROLLER_FOR: - *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR); - break; - case RelationType::DESCRIBED_BY: - *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIBED_BY); - break; - case RelationType::DESCRIPTION_FOR: - *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIPTION_FOR); - break; - case RelationType::EMBEDDED_BY: - *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDDED_BY); - break; - case RelationType::EMBEDS: - *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDS); - break; - case RelationType::FLOWS_FROM: - *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_FROM); - break; - case RelationType::FLOWS_TO: - *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_TO); - break; - case RelationType::LABEL_FOR: - *aRelationType = ::SysAllocString(IA2_RELATION_LABEL_FOR); - break; - case RelationType::LABELLED_BY: - *aRelationType = ::SysAllocString(IA2_RELATION_LABELED_BY); - break; - case RelationType::MEMBER_OF: - *aRelationType = ::SysAllocString(IA2_RELATION_MEMBER_OF); - break; - case RelationType::NODE_CHILD_OF: - *aRelationType = ::SysAllocString(IA2_RELATION_NODE_CHILD_OF); - break; - case RelationType::NODE_PARENT_OF: - *aRelationType = ::SysAllocString(IA2_RELATION_NODE_PARENT_OF); - break; - case RelationType::PARENT_WINDOW_OF: - *aRelationType = ::SysAllocString(IA2_RELATION_PARENT_WINDOW_OF); - break; - case RelationType::POPUP_FOR: - *aRelationType = ::SysAllocString(IA2_RELATION_POPUP_FOR); - break; - case RelationType::SUBWINDOW_OF: - *aRelationType = ::SysAllocString(IA2_RELATION_SUBWINDOW_OF); - break; +#include "RelationTypeMap.h" } return *aRelationType ? S_OK : E_OUTOFMEMORY; A11Y_TRYBLOCK_END } STDMETHODIMP @@ -161,9 +119,8 @@ ia2AccessibleRelation::get_targets(long for (long idx = 0; idx < maxTargets; idx++) get_target(idx, aTargets + idx); *aNTargets = maxTargets; return S_OK; A11Y_TRYBLOCK_END } -
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.h +++ b/accessible/src/windows/ia2/ia2AccessibleRelation.h @@ -7,16 +7,17 @@ #ifndef _NS_ACCESSIBLE_RELATION_WRAP_H #define _NS_ACCESSIBLE_RELATION_WRAP_H #include "Accessible.h" #include "IUnknownImpl.h" #include "nsIAccessibleRelation.h" +#include <utility> #include "nsTArray.h" #include "AccessibleRelation.h" namespace mozilla { namespace a11y { class ia2AccessibleRelation MOZ_FINAL : public IAccessibleRelation @@ -55,34 +56,27 @@ private: ia2AccessibleRelation& operator = (const ia2AccessibleRelation&); RelationType mType; nsTArray<nsRefPtr<Accessible> > mTargets; }; /** - * Relations exposed to IAccessible2. + * Gecko to IAccessible2 relation types map. */ -static const RelationType sRelationTypesForIA2[] = { - RelationType::LABELLED_BY, - RelationType::LABEL_FOR, - RelationType::DESCRIBED_BY, - RelationType::DESCRIPTION_FOR, - RelationType::NODE_CHILD_OF, - RelationType::NODE_PARENT_OF, - RelationType::CONTROLLED_BY, - RelationType::CONTROLLER_FOR, - RelationType::FLOWS_TO, - RelationType::FLOWS_FROM, - RelationType::MEMBER_OF, - RelationType::SUBWINDOW_OF, - RelationType::EMBEDS, - RelationType::EMBEDDED_BY, - RelationType::POPUP_FOR, - RelationType::PARENT_WINDOW_OF + +const WCHAR *const IA2_RELATION_NULL = L""; + +#define RELATIONTYPE(geckoType, name, atkType, msaaType, ia2Type) \ + std::pair<RelationType, const WCHAR *const>(RelationType::geckoType, ia2Type), + +static const std::pair<RelationType, const WCHAR *const> sRelationTypePairs[] = { +#include "RelationTypeMap.h" }; +#undef RELATIONTYPE + } // namespace a11y } // namespace mozilla #endif
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp +++ b/accessible/src/windows/msaa/AccessibleWrap.cpp @@ -893,16 +893,21 @@ AccessibleWrap::accNavigate( return E_INVALIDARG; if (accessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; Accessible* navAccessible = nullptr; Maybe<RelationType> xpRelation; +#define RELATIONTYPE(geckoType, stringType, atkType, msaaType, ia2Type) \ + case msaaType: \ + xpRelation.construct(RelationType::geckoType); \ + break; + switch(navDir) { case NAVDIR_FIRSTCHILD: if (!nsAccUtils::MustPrune(accessible)) navAccessible = accessible->FirstChild(); break; case NAVDIR_LASTCHILD: if (!nsAccUtils::MustPrune(accessible)) navAccessible = accessible->LastChild(); @@ -915,72 +920,24 @@ AccessibleWrap::accNavigate( break; case NAVDIR_DOWN: case NAVDIR_LEFT: case NAVDIR_RIGHT: case NAVDIR_UP: return E_NOTIMPL; // MSAA relationship extensions to accNavigate - case NAVRELATION_CONTROLLED_BY: - xpRelation.construct(RelationType::CONTROLLED_BY); - break; - case NAVRELATION_CONTROLLER_FOR: - xpRelation.construct(RelationType::CONTROLLER_FOR); - break; - case NAVRELATION_LABEL_FOR: - xpRelation.construct(RelationType::LABEL_FOR); - break; - case NAVRELATION_LABELLED_BY: - xpRelation.construct(RelationType::LABELLED_BY); - break; - case NAVRELATION_MEMBER_OF: - xpRelation.construct(RelationType::MEMBER_OF); - break; - case NAVRELATION_NODE_CHILD_OF: - xpRelation.construct(RelationType::NODE_CHILD_OF); - break; - case NAVRELATION_FLOWS_TO: - xpRelation.construct(RelationType::FLOWS_TO); - break; - case NAVRELATION_FLOWS_FROM: - xpRelation.construct(RelationType::FLOWS_FROM); - break; - case NAVRELATION_SUBWINDOW_OF: - xpRelation.construct(RelationType::SUBWINDOW_OF); - break; - case NAVRELATION_EMBEDS: - xpRelation.construct(RelationType::EMBEDS); - break; - case NAVRELATION_EMBEDDED_BY: - xpRelation.construct(RelationType::EMBEDDED_BY); - break; - case NAVRELATION_POPUP_FOR: - xpRelation.construct(RelationType::POPUP_FOR); - break; - case NAVRELATION_PARENT_WINDOW_OF: - xpRelation.construct(RelationType::PARENT_WINDOW_OF); - break; - case NAVRELATION_DEFAULT_BUTTON: - xpRelation.construct(RelationType::DEFAULT_BUTTON); - break; - case NAVRELATION_DESCRIBED_BY: - xpRelation.construct(RelationType::DESCRIBED_BY); - break; - case NAVRELATION_DESCRIPTION_FOR: - xpRelation.construct(RelationType::DESCRIPTION_FOR); - break; - case NAVRELATION_NODE_PARENT_OF: - xpRelation.construct(RelationType::NODE_PARENT_OF); - break; +#include "RelationTypeMap.h" default: return E_INVALIDARG; } +#undef RELATIONTYPE + pvarEndUpAt->vt = VT_EMPTY; if (!xpRelation.empty()) { Relation rel = RelationByType(xpRelation.ref()); navAccessible = rel.Next(); } if (!navAccessible)
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "ef355aa8244d698a5b226ac4ef2408a2eb0812bb", + "revision": "a57a913f1dd723afa191124f27b8d9fc4b0cb1c0", "repo_path": "/integration/gaia-central" }
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -589,17 +589,17 @@ pref("browser.gesture.pinch.in.shift", " #endif pref("browser.gesture.twist.latched", false); pref("browser.gesture.twist.threshold", 0); pref("browser.gesture.twist.right", "cmd_gestureRotateRight"); pref("browser.gesture.twist.left", "cmd_gestureRotateLeft"); pref("browser.gesture.twist.end", "cmd_gestureRotateEnd"); pref("browser.gesture.tap", "cmd_fullZoomReset"); -pref("browser.snapshots.limit", 0); +pref("browser.snapshots.limit", 5); // 0: Nothing happens // 1: Scrolling contents // 2: Go back or go forward, in your history // 3: Zoom in or out. #ifdef XP_MACOSX // On OS X, if the wheel has one axis only, shift+wheel comes through as a // horizontal scroll event. Thus, we can't assign anything other than normal
--- a/configure.in +++ b/configure.in @@ -217,27 +217,34 @@ if test -n "$gonkdir" ; then ARCH_DIR=arch-x86 ;; esac case "$ANDROID_VERSION" in 15) GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper" MOZ_B2G_BT=1 + MOZ_B2G_BT_BLUEZ=1 MOZ_B2G_CAMERA=1 MOZ_OMX_DECODER=1 AC_SUBST(MOZ_OMX_DECODER) MOZ_RTSP=1 ;; 17|18) GONK_INCLUDES="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include" if test -d "$gonkdir/external/bluetooth/bluez"; then - GONK_INCLUDES+=" -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib" + GONK_INCLUDES="$GONK_INCLUDES -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib" MOZ_B2G_BT=1 + MOZ_B2G_BT_BLUEZ=1 fi + if test -d "$gonkdir/external/bluetooth/bluedroid"; then + MOZ_B2G_BT=1 + MOZ_B2G_BT_BLUEDROID=1 + fi + MOZ_B2G_CAMERA=1 MOZ_OMX_DECODER=1 AC_SUBST(MOZ_OMX_DECODER) ;; *) AC_MSG_ERROR([Unsupported platform version: $ANDROID_VERSION]) ;; esac @@ -7296,16 +7303,18 @@ dnl ==================================== MOZ_ARG_ENABLE_BOOL(b2g-bt, [ --enable-b2g-bt Set compile flags necessary for compiling Bluetooth API for B2G ], MOZ_B2G_BT=1, MOZ_B2G_BT= ) if test -n "$MOZ_B2G_BT"; then AC_DEFINE(MOZ_B2G_BT) fi AC_SUBST(MOZ_B2G_BT) +AC_SUBST(MOZ_B2G_BT_BLUEZ) +AC_SUBST(MOZ_B2G_BT_BLUEDROID) dnl ======================================================== dnl = Enable Pico Speech Synthesis (Gonk usually) dnl ======================================================== MOZ_ARG_ENABLE_BOOL(synth-pico, [ --enable-synth-pico Set compile flags necessary for compiling Pico Web Speech API ], MOZ_SYNTH_PICO=1, MOZ_SYNTH_PICO= )
--- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -3114,30 +3114,34 @@ Element::GetMarkup(bool aIncludeSelf, ns nsIDocument* doc = OwnerDoc(); if (IsInHTMLDocument()) { Serialize(this, !aIncludeSelf, aMarkup); return; } nsAutoString contentType; doc->GetContentType(contentType); + bool tryToCacheEncoder = !aIncludeSelf; nsCOMPtr<nsIDocumentEncoder> docEncoder = doc->GetCachedEncoder(); if (!docEncoder) { docEncoder = do_CreateInstance(PromiseFlatCString( nsDependentCString(NS_DOC_ENCODER_CONTRACTID_BASE) + NS_ConvertUTF16toUTF8(contentType) ).get()); } if (!docEncoder) { // This could be some type for which we create a synthetic document. Try // again as XML contentType.AssignLiteral("application/xml"); docEncoder = do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "application/xml"); + // Don't try to cache the encoder since it would point to a different + // contentType once it has been reinitialized. + tryToCacheEncoder = false; } NS_ENSURE_TRUE_VOID(docEncoder); uint32_t flags = nsIDocumentEncoder::OutputEncodeBasicEntities | // Output DOM-standard newlines nsIDocumentEncoder::OutputLFLineBreak | // Don't do linebreaking that's not present in @@ -3158,17 +3162,17 @@ Element::GetMarkup(bool aIncludeSelf, ns if (aIncludeSelf) { docEncoder->SetNativeNode(this); } else { docEncoder->SetNativeContainerNode(this); } rv = docEncoder->EncodeToString(aMarkup); MOZ_ASSERT(NS_SUCCEEDED(rv)); - if (!aIncludeSelf) { + if (tryToCacheEncoder) { doc->SetCachedEncoder(docEncoder.forget()); } } /** * Fire mutation events for changes caused by parsing directly into a * context node. *
--- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -73,16 +73,17 @@ #include "GeckoProfiler.h" #include "nsObjectFrame.h" #include "nsDOMClassInfo.h" #include "nsWrapperCacheInlines.h" #include "nsDOMJSUtils.h" #include "nsWidgetsCID.h" #include "nsContentCID.h" +#include "mozilla/BasicEvents.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/Telemetry.h" #ifdef XP_WIN // Thanks so much, Microsoft! :( #ifdef CreateEvent #undef CreateEvent #endif
--- a/content/events/src/nsContentEventHandler.cpp +++ b/content/events/src/nsContentEventHandler.cpp @@ -21,16 +21,17 @@ #include "nsTextFrame.h" #include "nsISelectionController.h" #include "nsISelectionPrivate.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "nsIMEStateManager.h" #include "nsIObjectFrame.h" #include "mozilla/dom/Element.h" +#include "mozilla/TextEvents.h" #include <algorithm> using namespace mozilla; using namespace mozilla::dom; /******************************************************************/ /* nsContentEventHandler */ /******************************************************************/
--- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -9,16 +9,17 @@ #include "mozilla/MathAlgorithms.h" #include "mozilla/MouseEvents.h" #include "mozilla/TextEvents.h" #include "mozilla/TouchEvents.h" #include "mozilla/dom/TabParent.h" #include "nsCOMPtr.h" #include "nsEventStateManager.h" +#include "nsFocusManager.h" #include "nsIMEStateManager.h" #include "nsContentEventHandler.h" #include "nsIContent.h" #include "nsINodeInfo.h" #include "nsIDocument.h" #include "nsIFrame.h" #include "nsIWidget.h" #include "nsPresContext.h" @@ -1950,17 +1951,17 @@ nsEventStateManager::FireContextClick() if (frameSel && frameSel->GetMouseDownState()) { // note that this can cause selection changed events to fire if we're in // a text field, which will null out mCurrentTarget frameSel->SetMouseDownState(false); } } nsIDocument* doc = mGestureDownContent->GetCurrentDoc(); - nsAutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc); + AutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc); // dispatch to DOM nsEventDispatcher::Dispatch(mGestureDownContent, mPresContext, &event, nullptr, &status); // We don't need to dispatch to frame handling because no frames // watch NS_CONTEXTMENU except for nsMenuFrame and that's only for // dismissal. That's just as well since we don't really know @@ -5843,9 +5844,56 @@ nsEventStateManager::Prefs::GetAccessMod return sChromeAccessModifierMask; case nsIDocShellTreeItem::typeContent: return sContentAccessModifierMask; default: return 0; } } - +/******************************************************************/ +/* mozilla::AutoHandlingUserInputStatePusher */ +/******************************************************************/ + +AutoHandlingUserInputStatePusher::AutoHandlingUserInputStatePusher( + bool aIsHandlingUserInput, + WidgetEvent* aEvent, + nsIDocument* aDocument) : + mIsHandlingUserInput(aIsHandlingUserInput), + mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN), + mResetFMMouseDownState(false) +{ + if (!aIsHandlingUserInput) { + return; + } + nsEventStateManager::StartHandlingUserInput(); + if (!mIsMouseDown) { + return; + } + nsIPresShell::SetCapturingContent(nullptr, 0); + nsIPresShell::AllowMouseCapture(true); + if (!aDocument || !aEvent->mFlags.mIsTrusted) { + return; + } + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + NS_ENSURE_TRUE_VOID(fm); + fm->SetMouseButtonDownHandlingDocument(aDocument); + mResetFMMouseDownState = true; +} + +AutoHandlingUserInputStatePusher::~AutoHandlingUserInputStatePusher() +{ + if (!mIsHandlingUserInput) { + return; + } + nsEventStateManager::StopHandlingUserInput(); + if (!mIsMouseDown) { + return; + } + nsIPresShell::AllowMouseCapture(false); + if (!mResetFMMouseDownState) { + return; + } + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + NS_ENSURE_TRUE_VOID(fm); + fm->SetMouseButtonDownHandlingDocument(nullptr); +} +
--- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -1,30 +1,29 @@ /* -*- 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 nsEventStateManager_h__ #define nsEventStateManager_h__ -#include "mozilla/BasicEvents.h" #include "mozilla/EventForwards.h" #include "mozilla/TypedEnum.h" #include "nsIObserver.h" #include "nsWeakReference.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsCycleCollectionParticipant.h" -#include "nsFocusManager.h" #include "mozilla/TimeStamp.h" #include "nsIFrame.h" #include "Units.h" +class nsFrameLoader; class nsIContent; class nsIDocument; class nsIDocShell; class nsIDocShellTreeNode; class nsIDocShellTreeItem; class imgIContainer; class nsDOMDataTransfer; class MouseEnterLeaveDispatcher; @@ -842,73 +841,43 @@ public: mozilla::WidgetGUIEvent* aMouseDownEvent); void KillClickHoldTimer(); void FireContextClick(); void SetPointerLock(nsIWidget* aWidget, nsIContent* aElement) ; static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ; }; +namespace mozilla { + /** * This class is used while processing real user input. During this time, popups * are allowed. For mousedown events, mouse capturing is also permitted. */ -class nsAutoHandlingUserInputStatePusher +class AutoHandlingUserInputStatePusher { public: - nsAutoHandlingUserInputStatePusher(bool aIsHandlingUserInput, - mozilla::WidgetEvent* aEvent, - nsIDocument* aDocument) - : mIsHandlingUserInput(aIsHandlingUserInput), - mIsMouseDown(aEvent && aEvent->message == NS_MOUSE_BUTTON_DOWN), - mResetFMMouseDownState(false) - { - if (aIsHandlingUserInput) { - nsEventStateManager::StartHandlingUserInput(); - if (mIsMouseDown) { - nsIPresShell::SetCapturingContent(nullptr, 0); - nsIPresShell::AllowMouseCapture(true); - if (aDocument && aEvent->mFlags.mIsTrusted) { - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - fm->SetMouseButtonDownHandlingDocument(aDocument); - mResetFMMouseDownState = true; - } - } - } - } - } - - ~nsAutoHandlingUserInputStatePusher() - { - if (mIsHandlingUserInput) { - nsEventStateManager::StopHandlingUserInput(); - if (mIsMouseDown) { - nsIPresShell::AllowMouseCapture(false); - if (mResetFMMouseDownState) { - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - fm->SetMouseButtonDownHandlingDocument(nullptr); - } - } - } - } - } + AutoHandlingUserInputStatePusher(bool aIsHandlingUserInput, + WidgetEvent* aEvent, + nsIDocument* aDocument); + ~AutoHandlingUserInputStatePusher(); protected: bool mIsHandlingUserInput; bool mIsMouseDown; bool mResetFMMouseDownState; private: // Hide so that this class can only be stack-allocated static void* operator new(size_t /*size*/) CPP_THROW_NEW { return nullptr; } static void operator delete(void* /*memory*/) {} }; +} // namespace mozilla + // Click and double-click events need to be handled even for content that // has no frame. This is required for Web compatibility. #define NS_EVENT_NEEDS_FRAME(event) \ (!(event)->HasPluginActivationEventMessage() && \ (event)->message != NS_MOUSE_CLICK && \ (event)->message != NS_MOUSE_DOUBLECLICK) #endif // nsEventStateManager_h__
--- a/content/events/src/nsPrivateTextRange.h +++ b/content/events/src/nsPrivateTextRange.h @@ -5,17 +5,17 @@ #ifndef nsPrivateTextRange_h__ #define nsPrivateTextRange_h__ #include "nsIPrivateTextRange.h" #include "nsTArray.h" #include "nsAutoPtr.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange { NS_DECL_ISUPPORTS public: nsPrivateTextRange(const mozilla::TextRange &aTextRange); virtual ~nsPrivateTextRange(void);
--- a/content/html/content/src/HTMLAudioElement.cpp +++ b/content/html/content/src/HTMLAudioElement.cpp @@ -12,33 +12,28 @@ #include "nsGkAtoms.h" #include "nsIDocument.h" #include "jsfriendapi.h" #include "nsContentUtils.h" #include "nsJSUtils.h" #include "AudioSampleFormat.h" #include "AudioChannelCommon.h" #include <algorithm> -#include "mozilla/Preferences.h" #include "nsComponentManagerUtils.h" #include "nsIHttpChannel.h" #include "mozilla/dom/TimeRanges.h" #include "AudioStream.h" -static bool -IsAudioAPIEnabled() -{ - return mozilla::Preferences::GetBool("media.audio_data.enabled", true); -} - NS_IMPL_NS_NEW_HTML_ELEMENT(Audio) namespace mozilla { namespace dom { +extern bool IsAudioAPIEnabled(); + NS_IMPL_ISUPPORTS_INHERITED4(HTMLAudioElement, HTMLMediaElement, nsIDOMHTMLMediaElement, nsIDOMHTMLAudioElement, nsITimerCallback, nsIAudioChannelAgentCallback) NS_IMPL_ELEMENT_CLONE(HTMLAudioElement) HTMLAudioElement::HTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo)
--- a/content/html/content/src/HTMLFormElement.cpp +++ b/content/html/content/src/HTMLFormElement.cpp @@ -802,19 +802,19 @@ HTMLFormElement::SubmitSubmission(nsForm // // Submit // nsCOMPtr<nsIDocShell> docShell; { nsAutoPopupStatePusher popupStatePusher(mSubmitPopupState); - nsAutoHandlingUserInputStatePusher userInpStatePusher( - mSubmitInitiatedFromUserInput, - nullptr, doc); + AutoHandlingUserInputStatePusher userInpStatePusher( + mSubmitInitiatedFromUserInput, + nullptr, doc); nsCOMPtr<nsIInputStream> postDataStream; rv = aFormSubmission->GetEncodedSubmission(actionURI, getter_AddRefs(postDataStream)); NS_ENSURE_SUBMIT_SUCCESS(rv); rv = linkHandler->OnLinkClickSync(this, actionURI, target.get(),
--- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -987,16 +987,22 @@ static bool IsAutoplayEnabled() return Preferences::GetBool("media.autoplay.enabled"); } static bool UseAudioChannelService() { return Preferences::GetBool("media.useAudioChannelService"); } +// Not static because it's used in HTMLAudioElement. +bool IsAudioAPIEnabled() +{ + return mozilla::Preferences::GetBool("media.audio_data.enabled", false); +} + void HTMLMediaElement::UpdatePreloadAction() { PreloadAction nextAction = PRELOAD_UNDEFINED; // If autoplay is set, or we're playing, we should always preload data, // as we'll need it to play. if ((IsAutoplayEnabled() && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) || !mPaused) { @@ -1532,16 +1538,21 @@ NS_IMETHODIMP HTMLMediaElement::SetVolum ErrorResult rv; SetVolume(aVolume, rv); return rv.ErrorCode(); } uint32_t HTMLMediaElement::GetMozChannels(ErrorResult& aRv) const { + if (!IsAudioAPIEnabled()) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return 0; + } + if (!mDecoder && !mAudioStream) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return 0; } return mChannels; } @@ -1551,16 +1562,21 @@ HTMLMediaElement::GetMozChannels(uint32_ ErrorResult rv; *aMozChannels = GetMozChannels(rv); return rv.ErrorCode(); } uint32_t HTMLMediaElement::GetMozSampleRate(ErrorResult& aRv) const { + if (!IsAudioAPIEnabled()) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return 0; + } + if (!mDecoder && !mAudioStream) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return 0; } return mRate; } @@ -1642,16 +1658,21 @@ HTMLMediaElement::MozGetMetadata(JSConte } return rv.ErrorCode(); } uint32_t HTMLMediaElement::GetMozFrameBufferLength(ErrorResult& aRv) const { + if (!IsAudioAPIEnabled()) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return 0; + } + // The framebuffer (via MozAudioAvailable events) is only available // when reading vs. writing audio directly. if (!mDecoder) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return 0; } return mDecoder->GetFrameBufferLength(); @@ -1663,16 +1684,21 @@ HTMLMediaElement::GetMozFrameBufferLengt ErrorResult rv; *aMozFrameBufferLength = GetMozFrameBufferLength(rv); return rv.ErrorCode(); } void HTMLMediaElement::SetMozFrameBufferLength(uint32_t aMozFrameBufferLength, ErrorResult& aRv) { + if (!IsAudioAPIEnabled()) { + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } + if (!mDecoder) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } aRv = mDecoder->RequestFrameBufferLength(aMozFrameBufferLength); } @@ -3185,16 +3211,20 @@ nsresult HTMLMediaElement::DispatchAudio float aTime) { // Auto manage the memory for the frame buffer. If we fail and return // an error, this ensures we free the memory in the frame buffer. Otherwise // we hand off ownership of the frame buffer to the audioavailable event, // which frees the memory when it's destroyed. nsAutoArrayPtr<float> frameBuffer(aFrameBuffer); + if (!IsAudioAPIEnabled()) { + return NS_ERROR_DOM_NOT_SUPPORTED_ERR; + } + nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(OwnerDoc()); nsRefPtr<HTMLMediaElement> kungFuDeathGrip = this; NS_ENSURE_TRUE(domDoc, NS_ERROR_INVALID_ARG); nsCOMPtr<nsIDOMEvent> event; nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("MozAudioAvailableEvent"), getter_AddRefs(event)); nsCOMPtr<nsIDOMNotifyAudioAvailableEvent> audioavailableEvent(do_QueryInterface(event));
--- a/content/media/ogg/OggCodecState.cpp +++ b/content/media/ogg/OggCodecState.cpp @@ -57,17 +57,17 @@ static int64_t LEInt64(const unsigned ch // Reads a little-endian encoded unsigned 16bit integer at p. static uint16_t LEUint16(const unsigned char* p) { return p[0] + (p[1] << 8); } // Reads a little-endian encoded signed 16bit integer at p. -static int16_t LEInt16(const unsigned char* p) +inline int16_t LEInt16(const unsigned char* p) { return static_cast<int16_t>(LEUint16(p)); } /** Decoder base class for Ogg-encapsulated streams. */ OggCodecState* OggCodecState::Create(ogg_page* aPage) {
--- a/content/media/ogg/OggReader.cpp +++ b/content/media/ogg/OggReader.cpp @@ -54,17 +54,19 @@ extern PRLogModuleInfo* gMediaDecoderLog // lands between the seek target and SEEK_FUZZ_USECS microseconds before the // seek target. This is becaue it's usually quicker to just keep downloading // from an exisiting connection than to do another bisection inside that // small range, which would open a new HTTP connetion. static const uint32_t SEEK_FUZZ_USECS = 500000; // The number of microseconds of "pre-roll" we use for Opus streams. // The specification recommends 80 ms. +#ifdef MOZ_OPUS static const int64_t SEEK_OPUS_PREROLL = 80 * USECS_PER_MS; +#endif /* MOZ_OPUS */ enum PageSyncResult { PAGE_SYNC_ERROR = 1, PAGE_SYNC_END_OF_RANGE= 2, PAGE_SYNC_OK = 3 }; // Reads a page from the media resource. @@ -81,18 +83,20 @@ PageSync(MediaResource* aResource, // is about 4300 bytes, so we read the file in chunks larger than that. static const int PAGE_STEP = 8192; OggReader::OggReader(AbstractMediaDecoder* aDecoder) : MediaDecoderReader(aDecoder), mMonitor("OggReader"), mTheoraState(nullptr), mVorbisState(nullptr), +#ifdef MOZ_OPUS mOpusState(nullptr), mOpusEnabled(MediaDecoder::IsOpusEnabled()), +#endif /* MOZ_OPUS */ mSkeletonState(nullptr), mVorbisSerial(0), mOpusSerial(0), mTheoraSerial(0), mOpusPreSkip(0), mIsChained(false), mDecodedAudioFrames(0) { @@ -126,19 +130,21 @@ nsresult OggReader::ResetDecode(bool sta res = NS_ERROR_FAILURE; } // Discard any previously buffered packets/pages. ogg_sync_reset(&mOggState); if (mVorbisState && NS_FAILED(mVorbisState->Reset())) { res = NS_ERROR_FAILURE; } +#ifdef MOZ_OPUS if (mOpusState && NS_FAILED(mOpusState->Reset(start))) { res = NS_ERROR_FAILURE; } +#endif /* MOZ_OPUS */ if (mTheoraState && NS_FAILED(mTheoraState->Reset())) { res = NS_ERROR_FAILURE; } return res; } bool OggReader::ReadHeaders(OggCodecState* aState) @@ -157,18 +163,20 @@ bool OggReader::ReadHeaders(OggCodecStat void OggReader::BuildSerialList(nsTArray<uint32_t>& aTracks) { if (HasVideo()) { aTracks.AppendElement(mTheoraState->mSerial); } if (HasAudio()) { if (mVorbisState) { aTracks.AppendElement(mVorbisState->mSerial); - } else if(mOpusState) { +#ifdef MOZ_OPUS + } else if (mOpusState) { aTracks.AppendElement(mOpusState->mSerial); +#endif /* MOZ_OPUS */ } } } nsresult OggReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) { NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); @@ -215,27 +223,29 @@ nsresult OggReader::ReadMetadata(MediaIn if (codecState && codecState->GetType() == OggCodecState::TYPE_THEORA && !mTheoraState) { // First Theora bitstream, we'll play this one. Subsequent Theora // bitstreams will be ignored. mTheoraState = static_cast<TheoraState*>(codecState); } +#ifdef MOZ_OPUS if (codecState && codecState->GetType() == OggCodecState::TYPE_OPUS && !mOpusState) { if (mOpusEnabled) { mOpusState = static_cast<OpusState*>(codecState); } else { NS_WARNING("Opus decoding disabled." " See media.opus.enabled in about:config"); } } +#endif /* MOZ_OPUS */ if (codecState && codecState->GetType() == OggCodecState::TYPE_SKELETON && !mSkeletonState) { mSkeletonState = static_cast<SkeletonState*>(codecState); } } @@ -249,17 +259,20 @@ nsresult OggReader::ReadMetadata(MediaIn // We've read all BOS pages, so we know the streams contained in the media. // Now process all available header packets in the active Theora, Vorbis and // Skeleton streams. // Deactivate any non-primary bitstreams. for (uint32_t i = 0; i < bitstreams.Length(); i++) { OggCodecState* s = bitstreams[i]; - if (s != mVorbisState && s != mOpusState && + if (s != mVorbisState && +#ifdef MOZ_OPUS + s != mOpusState && +#endif /* MOZ_OPUS */ s != mTheoraState && s != mSkeletonState) { s->Deactivate(); } } if (mTheoraState && ReadHeaders(mTheoraState)) { nsIntRect picture = nsIntRect(mTheoraState->mInfo.pic_x, mTheoraState->mInfo.pic_y, @@ -600,26 +613,32 @@ void OggReader::DownmixToStereo(nsAutoAr #endif channels = out_channels; buffer = dBuffer; } bool OggReader::DecodeAudioData() { NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); - NS_ASSERTION(mVorbisState != nullptr || mOpusState != nullptr, - "Need audio codec state to decode audio"); + DebugOnly<bool> haveCodecState = mVorbisState != nullptr +#ifdef MOZ_OPUS + || mOpusState != nullptr +#endif /* MOZ_OPUS */ + ; + NS_ASSERTION(haveCodecState, "Need audio codec state to decode audio"); // Read the next data packet. Skip any non-data packets we encounter. ogg_packet* packet = 0; OggCodecState* codecState; if (mVorbisState) codecState = static_cast<OggCodecState*>(mVorbisState); +#ifdef MOZ_OPUS else codecState = static_cast<OggCodecState*>(mOpusState); +#endif /* MOZ_OPUS */ do { if (packet) { OggCodecState::ReleasePacket(packet); } packet = NextOggPacket(codecState); } while (packet && codecState->IsHeader(packet)); if (!packet) { @@ -656,17 +675,19 @@ void OggReader::SetChained(bool aIsChain ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); mDecoder->SetMediaSeekable(false); } } bool OggReader::ReadOggChain() { bool chained = false; +#ifdef MOZ_OPUS OpusState* newOpusState = nullptr; +#endif /* MOZ_OPUS */ VorbisState* newVorbisState = nullptr; int channels = 0; long rate = 0; MetadataTags* tags = nullptr; if (HasVideo() || HasSkeleton() || !HasAudio()) { return false; } @@ -1335,20 +1356,22 @@ nsresult OggReader::SeekInUnbuffered(int // don't do this offsetting when seeking in a buffered range, // as the extra decoding causes a noticeable speed hit when all the data // is buffered (compared to just doing a bisection to exactly find the // keyframe). int64_t keyframeOffsetMs = 0; if (HasVideo() && mTheoraState) { keyframeOffsetMs = mTheoraState->MaxKeyframeOffset(); } +#ifdef MOZ_OPUS // Add in the Opus pre-roll if necessary, as well. if (HasAudio() && mOpusState) { keyframeOffsetMs = std::max(keyframeOffsetMs, SEEK_OPUS_PREROLL); } +#endif /* MOZ_OPUS */ int64_t seekTarget = std::max(aStartTime, aTarget - keyframeOffsetMs); // Minimize the bisection search space using the known timestamps from the // buffered ranges. SeekRange k = SelectSeekRange(aRanges, seekTarget, aStartTime, aEndTime, false); return SeekBisection(seekTarget, k, SEEK_FUZZ_USECS); } nsresult OggReader::Seek(int64_t aTarget, @@ -1359,19 +1382,21 @@ nsresult OggReader::Seek(int64_t aTarget NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); if (mIsChained) return NS_ERROR_FAILURE; LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget)); nsresult res; MediaResource* resource = mDecoder->GetResource(); NS_ENSURE_TRUE(resource != nullptr, NS_ERROR_FAILURE); int64_t adjustedTarget = aTarget; +#ifdef MOZ_OPUS if (HasAudio() && mOpusState){ adjustedTarget = std::max(aStartTime, aTarget - SEEK_OPUS_PREROLL); } +#endif /* MOZ_OPUS */ if (adjustedTarget == aStartTime) { // We've seeked to the media start. Just seek to the offset of the first // content page. res = resource->Seek(nsISeekableStream::NS_SEEK_SET, 0); NS_ENSURE_SUCCESS(res,res); res = ResetDecode(true); @@ -1817,20 +1842,22 @@ nsresult OggReader::GetBuffered(TimeRang continue; } uint32_t serial = ogg_page_serialno(&page); if (mVorbisState && serial == mVorbisSerial) { startTime = VorbisState::Time(&mVorbisInfo, granulepos); NS_ASSERTION(startTime > 0, "Must have positive start time"); } +#ifdef MOZ_OPUS else if (mOpusState && serial == mOpusSerial) { startTime = OpusState::Time(mOpusPreSkip, granulepos); NS_ASSERTION(startTime > 0, "Must have positive start time"); } +#endif /* MOZ_OPUS */ else if (mTheoraState && serial == mTheoraSerial) { startTime = TheoraState::Time(&mTheoraInfo, granulepos); NS_ASSERTION(startTime > 0, "Must have positive start time"); } else if (mCodecStore.Contains(serial)) { // Stream is not the theora or vorbis stream we're playing, // but is one that we have header data for. startOffset += page.header_len + page.body_len;
--- a/content/media/ogg/OggReader.h +++ b/content/media/ogg/OggReader.h @@ -57,18 +57,21 @@ public: // If the Theora granulepos has not been captured, it may read several packets // until one with a granulepos has been captured, to ensure that all packets // read have valid time info. virtual bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold); virtual bool HasAudio() { - return (mVorbisState != 0 && mVorbisState->mActive) || - (mOpusState != 0 && mOpusState->mActive); + return (mVorbisState != 0 && mVorbisState->mActive) +#ifdef MOZ_OPUS + || (mOpusState != 0 && mOpusState->mActive) +#endif /* MOZ_OPUS */ + ; } virtual bool HasVideo() { return mTheoraState != 0 && mTheoraState->mActive; } virtual nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags); @@ -263,23 +266,25 @@ private: OggCodecStore mCodecStore; // Decode state of the Theora bitstream we're decoding, if we have video. TheoraState* mTheoraState; // Decode state of the Vorbis bitstream we're decoding, if we have audio. VorbisState* mVorbisState; +#ifdef MOZ_OPUS // Decode state of the Opus bitstream we're decoding, if we have one. OpusState *mOpusState; // Represents the user pref media.opus.enabled at the time our // contructor was called. We can't check it dynamically because // we're not on the main thread; bool mOpusEnabled; +#endif /* MOZ_OPUS */ // Decode state of the Skeleton bitstream. SkeletonState* mSkeletonState; // Ogg decoding state. ogg_sync_state mOggState; // Vorbis/Opus/Theora data used to compute timestamps. This is written on the
--- a/content/media/test/test_a4_tone.html +++ b/content/media/test/test_a4_tone.html @@ -10,19 +10,16 @@ https://bugzilla.mozilla.org/show_bug.cg <head> <title>Media test: simple audioAvalailable event checks</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a> -<!-- mute audio, since there is no need to hear the sound for these tests --> -<audio id='a1' controls></audio> - <pre id="test"> <script class="testbody" type="text/javascript"> /** * FFT is a class for calculating the Discrete Fourier Transform of a signal * with the Fast Fourier Transform algorithm. * * Source: github.com/corbanbrook/dsp.js; License: MIT; Copyright: Corban Brook @@ -238,27 +235,29 @@ function checkResults() { SimpleTest.finish(); } function audioEnded() { checkResults(); } function initTest() { - var a1 = document.getElementById('a1'); + var a1 = document.createElement("audio"); + a1.id = "a1"; a1.addEventListener("ended", audioEnded, false); a1.addEventListener("loadedmetadata", loadedMetadata, false); a1.addEventListener("MozAudioAvailable", audioAvailable, false); a1.src = testFile; a1.muted = true; a1.play(); + document.body.appendChild(a1); } window.addEventListener("load", function(e) { - initTest(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, initTest); }, false); SimpleTest.waitForExplicitFinish(); </script> </pre> </body> </html>
--- a/content/media/test/test_audio_event_adopt.html +++ b/content/media/test/test_audio_event_adopt.html @@ -19,19 +19,21 @@ https://bugzilla.mozilla.org/show_bug.cg return document.adoptNode(resultNode).checked; } function endTest() { is(wasAudioAvailableCalled(), true, "audioAvailable was not called"); SimpleTest.finish(); } function startTest() { - var audio = adopt(); - audio.addEventListener("ended", endTest, false); - audio.play(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, function () { + var audio = adopt(); + audio.addEventListener("ended", endTest, false); + audio.play(); + }); } SimpleTest.waitForExplicitFinish(); </script> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a>
--- a/content/media/test/test_audiowrite.html +++ b/content/media/test/test_audiowrite.html @@ -63,17 +63,17 @@ function runTests() { } catch(e) { writeArgsOK = true; } ok(writeArgsOK, "mozWriteAudio args test failed."); SimpleTest.finish(); } window.addEventListener("load", function(e) { - runTests(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, runTests); }, false); SimpleTest.waitForExplicitFinish(); </script> </pre> </body> </html>
--- a/content/media/test/test_bug686137.html +++ b/content/media/test/test_bug686137.html @@ -7,37 +7,41 @@ https://bugzilla.mozilla.org/show_bug.cg <head> <title>Media test: changing mozFrameBufferLength</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686137">Mozilla Bug 686137</a> -<audio id="a1" controls muted preload="metadata"></audio> - <pre id="test"> <script class="testbody" type="text/javascript"> -var testFile = "bug495794.ogg"; -var a1 = document.getElementById('a1'); + +SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, function () { + var a1 = document.createElement("audio"); + a1.controls = true; + a1.muted = true; + a1.preload = "metadata"; + a1.addEventListener("loadedmetadata", metaDataLoaded, false); + a1.src = "bug495794.ogg"; + a1.load(); +}); +SimpleTest.waitForExplicitFinish(); function audioAvailable(event) { + var a1 = event.target; a1.removeEventListener("MozAudioAvailable", audioAvailable); is( event.frameBuffer.length, 9001, "event.frameBuffer.length should be 9001."); is( event.frameBuffer.length, a1.mozFrameBufferLength, "event.frameBuffer.length should be " + a1.mozFrameBufferLength + "."); SimpleTest.finish(); } -function metaDataLoaded(){ +function metaDataLoaded(event){ + var a1 = event.target; a1.addEventListener("MozAudioAvailable", audioAvailable, false); a1.mozFrameBufferLength = 9001; a1.play(); } -a1.addEventListener("loadedmetadata", metaDataLoaded, false); -a1.src = testFile; -a1.load(); -SimpleTest.waitForExplicitFinish(); - </script> </pre> </body> </html>
--- a/content/media/test/test_framebuffer.html +++ b/content/media/test/test_framebuffer.html @@ -7,19 +7,16 @@ https://bugzilla.mozilla.org/show_bug.cg <head> <title>Media test: framebuffer size checks</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=490705">Mozilla Bug 490705</a> -<!-- mute audio, since there is no need to hear the sound for these tests --> -<audio id="a1" preload="metadata" controls></audio> - <pre id="test"> <script class="testbody" type="text/javascript"> var testFile = "bug495794.ogg"; var testFileDuration = 0.30; var testFileChannelCount = 2; var testFileSampleRate = 48000; var testFileFrameBufferLength = testFileChannelCount * 1024; @@ -79,27 +76,32 @@ function checkResults() { SimpleTest.finish(); } function audioEnded() { checkResults(); } function initTest() { - var a1 = document.getElementById('a1'); + var a1 = document.createElement("audio"); + a1.id = "a1"; + a1.preload = "metadata"; + a1.controls = true; + document.body.appendChild(a1); + a1.addEventListener("ended", audioEnded, false); a1.addEventListener("loadedmetadata", loadedMetadata, false); a1.addEventListener("MozAudioAvailable", audioAvailable, false); a1.src = testFile; a1.muted = true; a1.play(); } window.addEventListener("load", function(e) { - initTest(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, initTest); }, false); SimpleTest.waitForExplicitFinish(); </script> </pre> </body> </html>
--- a/content/media/test/test_wave_data_s16.html +++ b/content/media/test/test_wave_data_s16.html @@ -29,19 +29,22 @@ function audioavailable(e) { // Only care about the first few samples SimpleTest.finish(); } function startTest() { if (completed) return; - var v = document.getElementById('v'); - v.addEventListener('MozAudioAvailable', audioavailable, false); - v.play(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, + function () { + var v = document.getElementById('v'); + v.addEventListener('MozAudioAvailable', audioavailable, false); + v.play(); + }); } SimpleTest.waitForExplicitFinish(); </script> </pre> <audio id='v' preload="metadata" onloadedmetadata='return startTest();'>
--- a/content/media/test/test_wave_data_u8.html +++ b/content/media/test/test_wave_data_u8.html @@ -29,19 +29,22 @@ function audioavailable(e) { // Only care about the first few samples SimpleTest.finish(); } function startTest() { if (completed) return; - var v = document.getElementById('v'); - v.addEventListener('MozAudioAvailable', audioavailable, false); - v.play(); + SpecialPowers.pushPrefEnv({"set": [["media.audio_data.enabled", true]]}, + function () { + var v = document.getElementById('v'); + v.addEventListener('MozAudioAvailable', audioavailable, false); + v.play(); + }); } SimpleTest.waitForExplicitFinish(); </script> </pre> <audio id='v' preload="metadata" onloadedmetadata='return startTest();'>
--- a/content/media/webaudio/test/mochitest.ini +++ b/content/media/webaudio/test/mochitest.ini @@ -106,8 +106,9 @@ support-files = [test_scriptProcessorNodeChannelCount.html] [test_scriptProcessorNodeZeroInputOutput.html] [test_singleSourceDest.html] [test_waveShaper.html] [test_waveShaperNoCurve.html] [test_waveShaperZeroLengthCurve.html] [test_audioDestinationNode.html] [test_mozaudiochannel.html] +[test_waveDecoder.html]
new file mode 100644 --- /dev/null +++ b/content/media/webaudio/test/test_waveDecoder.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<meta charset=utf-8> +<head> + <title>Test that we decode uint8 and sint16 wave files with correct conversion to float64</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var testsDone = 0; +var tests = ["UklGRjUrAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YQMAAAD/AIA=", + "UklGRkZWAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YQYAAAD/fwCAAAA="]; + +SimpleTest.waitForExplicitFinish(); + +function base64ToUint8Buffer(b64) { + var str = atob(b64) + var u8 = new Uint8Array(str.length); + for (var i = 0; i < str.length; ++i) { + u8[i] = str.charCodeAt(i); + } + return u8; +} + +function fixupBufferSampleRate(u8, rate) { + u8[24] = (rate & 0x000000ff) >> 0; + u8[25] = (rate & 0x0000ff00) >> 8; + u8[26] = (rate & 0x00ff0000) >> 16; + u8[27] = (rate & 0xff000000) >> 24; +} + +function finishTest() { + testsDone += 1; + if (testsDone == tests.length) { + SimpleTest.finish(); + } +} + +function decodeComplete(b) { + ok(true, "Decoding succeeded."); + is(b.numberOfChannels, 1, "Should have 1 channel."); + is(b.length, 3, "Should have three samples."); + var samples = b.getChannelData(0); + ok(samples[0] > 0.99 && samples[0] < 1.01, "Check near 1.0. Got " + samples[0]); + ok(samples[1] > -1.01 && samples[1] < -0.99, "Check near -1.0. Got " + samples[1]); + ok(samples[2] > -0.01 && samples[2] < 0.01, "Check near 0.0. Got " + samples[2]); + finishTest(); +} + +function decodeFailed() { + ok(false, "Decoding failed."); + finishTest(); +} + +addLoadEvent(function() { + var context = new AudioContext(); + + for (var i = 0; i < tests.length; ++i) { + var u8 = base64ToUint8Buffer(tests[i]); + fixupBufferSampleRate(u8, context.sampleRate); + context.decodeAudioData(u8.buffer, decodeComplete, decodeFailed); + } +}); +</script> +</pre> +</body> +</html>
--- a/dom/apps/src/InterAppComm.cpp +++ b/dom/apps/src/InterAppComm.cpp @@ -7,17 +7,17 @@ #include "nsPIDOMWindow.h" #include "nsJSPrincipals.h" #include "mozilla/Preferences.h" #include "AccessCheck.h" using namespace mozilla::dom; /* static */ bool -InterAppComm::EnabledForScope(JSContext* /* unused */, JSObject* aObj) +InterAppComm::EnabledForScope(JSContext* /* unused */, JS::Handle<JSObject*> aObj) { // Disable the constructors if they're disabled by the preference for sure. if (!Preferences::GetBool("dom.inter-app-communication-api.enabled", false)) { return false; } // Only expose the constructors to the chrome codes for Gecko internal uses. // The content pages shouldn't be aware of the constructors.
--- a/dom/apps/src/InterAppComm.h +++ b/dom/apps/src/InterAppComm.h @@ -12,15 +12,15 @@ struct JSContext; class JSObject; namespace mozilla { namespace dom { class InterAppComm { public: - static bool EnabledForScope(JSContext* /* unused */, JSObject* aObj); + static bool EnabledForScope(JSContext* /* unused */, JS::Handle<JSObject*> aObj); }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_apps_InterAppComm_h
--- a/dom/base/CompositionStringSynthesizer.h +++ b/dom/base/CompositionStringSynthesizer.h @@ -6,17 +6,17 @@ #ifndef mozilla_dom_compositionstringsynthesizer_h__ #define mozilla_dom_compositionstringsynthesizer_h__ #include "nsICompositionStringSynthesizer.h" #include "nsString.h" #include "nsTArray.h" #include "nsWeakReference.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class nsIWidget; class nsPIDOMWindow; namespace mozilla { namespace dom { class CompositionStringSynthesizer MOZ_FINAL :
--- a/dom/base/nsWindowMemoryReporter.cpp +++ b/dom/base/nsWindowMemoryReporter.cpp @@ -3,16 +3,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 "amIAddonManager.h" #include "nsWindowMemoryReporter.h" #include "nsGlobalWindow.h" #include "nsIDocument.h" +#include "nsIDOMWindowCollection.h" #include "nsIEffectiveTLDService.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" #include "mozilla/StaticPtr.h" #include "nsNetCID.h" #include "nsPrintfCString.h" #include "XPCJSMemoryReporter.h" @@ -26,24 +27,80 @@ StaticRefPtr<nsWindowMemoryReporter> sWi nsWindowMemoryReporter::nsWindowMemoryReporter() : mCheckForGhostWindowsCallbackPending(false) { } NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryReporter, nsIObserver, nsSupportsWeakReference) -/* static */ -void +static nsresult +AddNonJSSizeOfWindowAndItsDescendents(nsGlobalWindow* aWindow, + nsTabSizes* aSizes) +{ + // Measure the window. + nsWindowSizes windowSizes(moz_malloc_size_of); + aWindow->AddSizeOfIncludingThis(&windowSizes); + windowSizes.addToTabSizes(aSizes); + + // Measure the inner window, if there is one. + nsWindowSizes innerWindowSizes(moz_malloc_size_of); + nsGlobalWindow* inner = aWindow->GetCurrentInnerWindowInternal(); + if (inner) { + inner->AddSizeOfIncludingThis(&innerWindowSizes); + innerWindowSizes.addToTabSizes(aSizes); + } + + nsCOMPtr<nsIDOMWindowCollection> frames; + nsresult rv = aWindow->GetFrames(getter_AddRefs(frames)); + NS_ENSURE_SUCCESS(rv, rv); + + uint32_t length; + rv = frames->GetLength(&length); + NS_ENSURE_SUCCESS(rv, rv); + + // Measure this window's descendents. + for (uint32_t i = 0; i < length; i++) { + nsCOMPtr<nsIDOMWindow> child; + rv = frames->Item(i, getter_AddRefs(child)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_STATE(child); + + nsGlobalWindow* childWin = + static_cast<nsGlobalWindow*>(static_cast<nsIDOMWindow *>(child.get())); + + rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; +} + +static nsresult +NonJSSizeOfTab(nsPIDOMWindow* aWindow, size_t* aDomSize, size_t* aStyleSize, size_t* aOtherSize) +{ + nsGlobalWindow* window = static_cast<nsGlobalWindow*>(aWindow); + + nsTabSizes sizes; + nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(window, &sizes); + NS_ENSURE_SUCCESS(rv, rv); + + *aDomSize = sizes.mDom; + *aStyleSize = sizes.mStyle; + *aOtherSize = sizes.mOther; + return NS_OK; +} + +/* static */ void nsWindowMemoryReporter::Init() { MOZ_ASSERT(!sWindowReporter); sWindowReporter = new nsWindowMemoryReporter(); ClearOnShutdown(&sWindowReporter); NS_RegisterMemoryReporter(sWindowReporter); + RegisterNonJSSizeOfTab(NonJSSizeOfTab); nsCOMPtr<nsIObserverService> os = services::GetObserverService(); if (os) { // DOM_WINDOW_DESTROYED_TOPIC announces what we call window "detachment", // when a window's docshell is set to NULL. os->AddObserver(sWindowReporter, DOM_WINDOW_DESTROYED_TOPIC, /* weakRef = */ true); os->AddObserver(sWindowReporter, "after-minimize-memory-usage",
--- a/dom/base/nsWindowMemoryReporter.h +++ b/dom/base/nsWindowMemoryReporter.h @@ -7,48 +7,69 @@ #ifndef nsWindowMemoryReporter_h__ #define nsWindowMemoryReporter_h__ #include "nsIMemoryReporter.h" #include "nsIObserver.h" #include "nsDataHashtable.h" #include "nsWeakReference.h" #include "nsAutoPtr.h" +#include "mozilla/Attributes.h" +#include "mozilla/Assertions.h" #include "mozilla/MemoryReporting.h" +#include "mozilla/PodOperations.h" #include "mozilla/TimeStamp.h" #include "nsArenaMemoryStats.h" -#include "mozilla/Attributes.h" // This should be used for any nsINode sub-class that has fields of its own // that it needs to measure; any sub-class that doesn't use it will inherit // SizeOfExcludingThis from its super-class. SizeOfIncludingThis() need not be // defined, it is inherited from nsINode. #define NS_DECL_SIZEOF_EXCLUDING_THIS \ virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; class nsWindowSizes { +#define FOR_EACH_SIZE(macro) \ + macro(DOM, mDOMElementNodes) \ + macro(DOM, mDOMTextNodes) \ + macro(DOM, mDOMCDATANodes) \ + macro(DOM, mDOMCommentNodes) \ + macro(DOM, mDOMEventTargets) \ + macro(DOM, mDOMOther) \ + macro(Style, mStyleSheets) \ + macro(Other, mLayoutPresShell) \ + macro(Style, mLayoutStyleSets) \ + macro(Other, mLayoutTextRuns) \ + macro(Other, mLayoutPresContext) \ + macro(Other, mPropertyTables) \ + public: - nsWindowSizes(mozilla::MallocSizeOf aMallocSizeOf) { - memset(this, 0, sizeof(nsWindowSizes)); - mMallocSizeOf = aMallocSizeOf; + nsWindowSizes(mozilla::MallocSizeOf aMallocSizeOf) + : + #define ZERO_SIZE(kind, mSize) mSize(0), + FOR_EACH_SIZE(ZERO_SIZE) + #undef ZERO_SIZE + mArenaStats(), + mMallocSizeOf(aMallocSizeOf) + {} + + void addToTabSizes(nsTabSizes *sizes) const { + #define ADD_TO_TAB_SIZES(kind, mSize) sizes->add(nsTabSizes::kind, mSize); + FOR_EACH_SIZE(ADD_TO_TAB_SIZES) + #undef ADD_TO_TAB_SIZES + mArenaStats.addToTabSizes(sizes); } - mozilla::MallocSizeOf mMallocSizeOf; + + #define DECL_SIZE(kind, mSize) size_t mSize; + FOR_EACH_SIZE(DECL_SIZE); + #undef DECL_SIZE nsArenaMemoryStats mArenaStats; - size_t mDOMElementNodes; - size_t mDOMTextNodes; - size_t mDOMCDATANodes; - size_t mDOMCommentNodes; - size_t mDOMEventTargets; - size_t mDOMOther; - size_t mStyleSheets; - size_t mLayoutPresShell; - size_t mLayoutStyleSets; - size_t mLayoutTextRuns; - size_t mLayoutPresContext; - size_t mPropertyTables; + mozilla::MallocSizeOf mMallocSizeOf; + +#undef FOR_EACH_SIZE }; /** * nsWindowMemoryReporter is responsible for the 'explicit/window-objects' * memory reporter. * * We classify DOM window objects into one of three categories: *
--- a/dom/bluetooth/BluetoothHfpManager.cpp +++ b/dom/bluetooth/BluetoothHfpManager.cpp @@ -556,18 +556,17 @@ BluetoothHfpManager::HandleVolumeChanged void BluetoothHfpManager::HandleVoiceConnectionChanged() { nsCOMPtr<nsIMobileConnectionProvider> connection = do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE_VOID(connection); nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo; - // TODO: Bug 921991 - B2G BT: support multiple sim cards - connection->GetVoiceConnectionInfo(0, getter_AddRefs(voiceInfo)); + connection->GetVoiceConnectionInfo(getter_AddRefs(voiceInfo)); NS_ENSURE_TRUE_VOID(voiceInfo); nsString type; voiceInfo->GetType(type); mPhoneType = GetPhoneType(type); bool roaming; voiceInfo->GetRoaming(&roaming); @@ -593,18 +592,17 @@ BluetoothHfpManager::HandleVoiceConnecti /** * Possible return values for mode are: * - null (unknown): set mNetworkSelectionMode to 0 (auto) * - automatic: set mNetworkSelectionMode to 0 (auto) * - manual: set mNetworkSelectionMode to 1 (manual) */ nsString mode; - // TODO: Bug 921991 - B2G BT: support multiple sim cards - connection->GetNetworkSelectionMode(0, mode); + connection->GetNetworkSelectionMode(mode); if (mode.EqualsLiteral("manual")) { mNetworkSelectionMode = 1; } else { mNetworkSelectionMode = 0; } nsCOMPtr<nsIDOMMozMobileNetworkInfo> network; voiceInfo->GetNetwork(getter_AddRefs(network));
--- a/dom/bluetooth/BluetoothRilListener.cpp +++ b/dom/bluetooth/BluetoothRilListener.cpp @@ -287,32 +287,30 @@ BluetoothRilListener::StopIccListening() bool BluetoothRilListener::StartMobileConnectionListening() { nsCOMPtr<nsIMobileConnectionProvider> provider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - // TODO: Bug 921991 - B2G BT: support multiple sim cards nsresult rv = provider-> - RegisterMobileConnectionMsg(0, mMobileConnectionListener); + RegisterMobileConnectionMsg(mMobileConnectionListener); return NS_SUCCEEDED(rv); } bool BluetoothRilListener::StopMobileConnectionListening() { nsCOMPtr<nsIMobileConnectionProvider> provider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID); NS_ENSURE_TRUE(provider, false); - // TODO: Bug 921991 - B2G BT: support multiple sim cards nsresult rv = provider-> - UnregisterMobileConnectionMsg(0, mMobileConnectionListener); + UnregisterMobileConnectionMsg(mMobileConnectionListener); return NS_SUCCEEDED(rv); } bool BluetoothRilListener::StartTelephonyListening() { nsCOMPtr<nsITelephonyProvider> provider = do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
--- a/dom/bluetooth/BluetoothService.cpp +++ b/dom/bluetooth/BluetoothService.cpp @@ -39,17 +39,21 @@ #include "nsXPCOM.h" #if defined(MOZ_WIDGET_GONK) #include "cutils/properties.h" #endif #if defined(MOZ_B2G_BT) # if defined(MOZ_BLUETOOTH_GONK) -# include "BluetoothGonkService.h" +#ifdef MOZ_B2G_BT_BLUEZ +#include "BluetoothGonkService.h" +#else +#include "BluetoothServiceBluedroid.h" +#endif # elif defined(MOZ_BLUETOOTH_DBUS) # include "BluetoothDBusService.h" # else # error No_suitable_backend_for_bluetooth! # endif #endif #define MOZSETTINGS_CHANGED_ID "mozsettings-changed" @@ -299,20 +303,26 @@ BluetoothService::Create() { #if defined(MOZ_B2G_BT) if (!IsMainProcess()) { return BluetoothServiceChildProcess::Create(); } #endif #if defined(MOZ_BLUETOOTH_GONK) +#ifdef MOZ_B2G_BT_BLUEDROID + return new BluetoothServiceBluedroid(); +#else return new BluetoothGonkService(); +#endif #elif defined(MOZ_BLUETOOTH_DBUS) +#ifdef MOZ_B2G_BT_BLUEZ return new BluetoothDBusService(); #endif +#endif BT_WARNING("No platform support for bluetooth!"); return nullptr; } bool BluetoothService::Init() { MOZ_ASSERT(NS_IsMainThread());
new file mode 100644 --- /dev/null +++ b/dom/bluetooth/BluetoothServiceBluedroid.cpp @@ -0,0 +1,341 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- +/* vim: set ts=2 et sw=2 tw=80: */ +/* +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include "BluetoothServiceBluedroid.h" +#include "BluetoothReplyRunnable.h" +#include "BluetoothUtils.h" +#include "BluetoothUuid.h" +#include "mozilla/dom/bluetooth/BluetoothTypes.h" +#include "mozilla/ipc/UnixSocket.h" + +using namespace mozilla; +using namespace mozilla::ipc; +USING_BLUETOOTH_NAMESPACE + +nsresult +BluetoothServiceBluedroid::StartInternal() +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::StopInternal() +{ + return NS_OK; +} + +bool +BluetoothServiceBluedroid::IsEnabledInternal() +{ + return true; +} + +nsresult +BluetoothServiceBluedroid::GetDefaultAdapterPathInternal( + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal( + uint16_t aProfileId, BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; + +} + +nsresult +BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal( + const nsTArray<nsString>& aDeviceAddress, BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::StartDiscoveryInternal( + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::StopDiscoveryInternal( + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::GetDevicePropertiesInternal( + const BluetoothSignal& aSignal) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType, + const BluetoothNamedValue& aValue, + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +bool +BluetoothServiceBluedroid::GetDevicePath(const nsAString& aAdapterPath, + const nsAString& aDeviceAddress, + nsAString& aDevicePath) +{ + return true; +} + +bool +BluetoothServiceBluedroid::AddServiceRecords(const char* serviceName, + unsigned long long uuidMsb, + unsigned long long uuidLsb, + int channel) +{ + return true; +} + +bool +BluetoothServiceBluedroid::RemoveServiceRecords(const char* serviceName, + unsigned long long uuidMsb, + unsigned long long uuidLsb, + int channel) +{ + return true; +} + +bool +BluetoothServiceBluedroid::AddReservedServicesInternal( + const nsTArray<uint32_t>& aServices, + nsTArray<uint32_t>& aServiceHandlesContainer) +{ + return true; + +} + +bool +BluetoothServiceBluedroid::RemoveReservedServicesInternal( + const nsTArray<uint32_t>& aServiceHandles) +{ + return true; +} + +nsresult +BluetoothServiceBluedroid::GetScoSocket( + const nsAString& aObjectPath, bool aAuth, bool aEncrypt, + mozilla::ipc::UnixSocketConsumer* aConsumer) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::GetServiceChannel( + const nsAString& aDeviceAddress, + const nsAString& aServiceUuid, + BluetoothProfileManagerBase* aManager) +{ + return NS_OK; +} + +bool +BluetoothServiceBluedroid::UpdateSdpRecords( + const nsAString& aDeviceAddress, + BluetoothProfileManagerBase* aManager) +{ + return true; +} + +nsresult +BluetoothServiceBluedroid::CreatePairedDeviceInternal( + const nsAString& aDeviceAddress, int aTimeout, + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::RemoveDeviceInternal( + const nsAString& aDeviceObjectPath, + BluetoothReplyRunnable* aRunnable) +{ + return NS_OK; +} + +bool +BluetoothServiceBluedroid::SetPinCodeInternal( + const nsAString& aDeviceAddress, const nsAString& aPinCode, + BluetoothReplyRunnable* aRunnable) +{ + return true; +} + +bool +BluetoothServiceBluedroid::SetPasskeyInternal( + const nsAString& aDeviceAddress, uint32_t aPasskey, + BluetoothReplyRunnable* aRunnable) +{ + return true; +} + +bool +BluetoothServiceBluedroid::SetPairingConfirmationInternal( + const nsAString& aDeviceAddress, bool aConfirm, + BluetoothReplyRunnable* aRunnable) +{ + return true; +} + +bool +BluetoothServiceBluedroid::SetAuthorizationInternal( + const nsAString& aDeviceAddress, bool aAllow, + BluetoothReplyRunnable* aRunnable) +{ + return true; +} + +nsresult +BluetoothServiceBluedroid::PrepareAdapterInternal() +{ + return NS_OK; +} + +void +BluetoothServiceBluedroid::Connect(const nsAString& aDeviceAddress, + uint32_t aCod, + uint16_t aServiceUuid, + BluetoothReplyRunnable* aRunnable) +{ + +} + +bool +BluetoothServiceBluedroid::IsConnected(uint16_t aProfileId) +{ + return true; +} + +void +BluetoothServiceBluedroid::Disconnect( + const nsAString& aDeviceAddress, uint16_t aServiceUuid, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress, + BlobParent* aBlobParent, + BlobChild* aBlobChild, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::StopSendingFile(const nsAString& aDeviceAddress, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::ConfirmReceivingFile( + const nsAString& aDeviceAddress, bool aConfirm, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::ConnectSco(BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::DisconnectSco(BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::IsScoConnected(BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::SendMetaData(const nsAString& aTitle, + const nsAString& aArtist, + const nsAString& aAlbum, + int64_t aMediaNumber, + int64_t aTotalMediaCount, + int64_t aDuration, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::SendPlayStatus( + int64_t aDuration, int64_t aPosition, + const nsAString& aPlayStatus, + BluetoothReplyRunnable* aRunnable) +{ + +} + +void +BluetoothServiceBluedroid::UpdatePlayStatus( + uint32_t aDuration, uint32_t aPosition, ControlPlayStatus aPlayStatus) +{ + +} + +nsresult +BluetoothServiceBluedroid::SendSinkMessage(const nsAString& aDeviceAddresses, + const nsAString& aMessage) +{ + return NS_OK; +} + +nsresult +BluetoothServiceBluedroid::SendInputMessage(const nsAString& aDeviceAddresses, + const nsAString& aMessage) +{ + return NS_OK; +} + +void +BluetoothServiceBluedroid::AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) +{ +} + +void +BluetoothServiceBluedroid::IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) +{ +} + +void +BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable) +{ +} +
new file mode 100644 --- /dev/null +++ b/dom/bluetooth/BluetoothServiceBluedroid.h @@ -0,0 +1,189 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_bluetooth_bluetoothservicebluedroid_h__ +#define mozilla_dom_bluetooth_bluetoothservicebluedroid_h__ + +#include "BluetoothCommon.h" +#include "BluetoothService.h" + +class DBusMessage; + +BEGIN_BLUETOOTH_NAMESPACE + +class BluetoothServiceBluedroid : public BluetoothService +{ +public: + virtual nsresult StartInternal(); + virtual nsresult StopInternal(); + virtual bool IsEnabledInternal(); + + virtual nsresult GetDefaultAdapterPathInternal( + BluetoothReplyRunnable* aRunnable); + + virtual nsresult GetConnectedDevicePropertiesInternal(uint16_t aProfileId, + BluetoothReplyRunnable* aRunnable); + + virtual nsresult GetPairedDevicePropertiesInternal( + const nsTArray<nsString>& aDeviceAddress, + BluetoothReplyRunnable* aRunnable); + + virtual nsresult StartDiscoveryInternal(BluetoothReplyRunnable* aRunnable); + virtual nsresult StopDiscoveryInternal(BluetoothReplyRunnable* aRunnable); + + virtual nsresult + GetDevicePropertiesInternal(const BluetoothSignal& aSignal); + + virtual nsresult + SetProperty(BluetoothObjectType aType, + const BluetoothNamedValue& aValue, + BluetoothReplyRunnable* aRunnable); + + virtual bool + GetDevicePath(const nsAString& aAdapterPath, + const nsAString& aDeviceAddress, + nsAString& aDevicePath); + + static bool + AddServiceRecords(const char* serviceName, + unsigned long long uuidMsb, + unsigned long long uuidLsb, + int channel); + + static bool + RemoveServiceRecords(const char* serviceName, + unsigned long long uuidMsb, + unsigned long long uuidLsb, + int channel); + + static bool + AddReservedServicesInternal(const nsTArray<uint32_t>& aServices, + nsTArray<uint32_t>& aServiceHandlesContainer); + + static bool + RemoveReservedServicesInternal(const nsTArray<uint32_t>& aServiceHandles); + + virtual nsresult + GetScoSocket(const nsAString& aObjectPath, + bool aAuth, + bool aEncrypt, + mozilla::ipc::UnixSocketConsumer* aConsumer); + + virtual nsresult + GetServiceChannel(const nsAString& aDeviceAddress, + const nsAString& aServiceUuid, + BluetoothProfileManagerBase* aManager); + + virtual bool + UpdateSdpRecords(const nsAString& aDeviceAddress, + BluetoothProfileManagerBase* aManager); + + virtual nsresult + CreatePairedDeviceInternal(const nsAString& aDeviceAddress, + int aTimeout, + BluetoothReplyRunnable* aRunnable); + + virtual nsresult + RemoveDeviceInternal(const nsAString& aDeviceObjectPath, + BluetoothReplyRunnable* aRunnable); + + virtual bool + SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode, + BluetoothReplyRunnable* aRunnable); + + virtual bool + SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey, + BluetoothReplyRunnable* aRunnable); + + virtual bool + SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm, + BluetoothReplyRunnable* aRunnable); + + virtual bool + SetAuthorizationInternal(const nsAString& aDeviceAddress, bool aAllow, + BluetoothReplyRunnable* aRunnable); + + virtual nsresult + PrepareAdapterInternal(); + + virtual void + Connect(const nsAString& aDeviceAddress, + uint32_t aCod, + uint16_t aServiceUuid, + BluetoothReplyRunnable* aRunnable); + + virtual bool + IsConnected(uint16_t aProfileId); + + virtual void + Disconnect(const nsAString& aDeviceAddress, uint16_t aServiceUuid, + BluetoothReplyRunnable* aRunnable); + + virtual void + SendFile(const nsAString& aDeviceAddress, + BlobParent* aBlobParent, + BlobChild* aBlobChild, + BluetoothReplyRunnable* aRunnable); + + virtual void + StopSendingFile(const nsAString& aDeviceAddress, + BluetoothReplyRunnable* aRunnable); + + virtual void + ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirm, + BluetoothReplyRunnable* aRunnable); + + virtual void + ConnectSco(BluetoothReplyRunnable* aRunnable); + + virtual void + DisconnectSco(BluetoothReplyRunnable* aRunnable); + + virtual void + IsScoConnected(BluetoothReplyRunnable* aRunnable); + + virtual void + AnswerWaitingCall(BluetoothReplyRunnable* aRunnable); + + virtual void + IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable); + + virtual void + ToggleCalls(BluetoothReplyRunnable* aRunnable); + + virtual void + SendMetaData(const nsAString& aTitle, + const nsAString& aArtist, + const nsAString& aAlbum, + int64_t aMediaNumber, + int64_t aTotalMediaCount, + int64_t aDuration, + BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE; + + virtual void + SendPlayStatus(int64_t aDuration, + int64_t aPosition, + const nsAString& aPlayStatus, + BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE; + + virtual void + UpdatePlayStatus(uint32_t aDuration, + uint32_t aPosition, + ControlPlayStatus aPlayStatus) MOZ_OVERRIDE; + + virtual nsresult + SendSinkMessage(const nsAString& aDeviceAddresses, + const nsAString& aMessage) MOZ_OVERRIDE; + + virtual nsresult + SendInputMessage(const nsAString& aDeviceAddresses, + const nsAString& aMessage) MOZ_OVERRIDE; +}; + +END_BLUETOOTH_NAMESPACE + +#endif +
--- a/dom/bluetooth/BluetoothUnixSocketConnector.cpp +++ b/dom/bluetooth/BluetoothUnixSocketConnector.cpp @@ -22,32 +22,34 @@ */ #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/socket.h> +#ifdef MOZ_B2G_BT_BLUEZ #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h> #include <bluetooth/rfcomm.h> #include <bluetooth/sco.h> - +#endif #include "BluetoothUnixSocketConnector.h" #include "nsThreadUtils.h" using namespace mozilla::ipc; USING_BLUETOOTH_NAMESPACE static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer static const int L2CAP_SO_SNDBUF = 400 * 1024; // 400 KB send buffer static const int L2CAP_SO_RCVBUF = 400 * 1024; // 400 KB receive buffer static const int L2CAP_MAX_MTU = 65000; +#ifdef MOZ_B2G_BT_BLUEZ static int get_bdaddr(const char *str, bdaddr_t *ba) { char *d = ((char*)ba) + 5, *endp; for (int i = 0; i < 6; i++) { *d-- = strtol(str, &endp, 16); MOZ_ASSERT(!(*endp != ':' && i != 5)); str = endp + 1; @@ -57,30 +59,33 @@ int get_bdaddr(const char *str, bdaddr_t static void get_bdaddr_as_string(const bdaddr_t *ba, char *str) { const uint8_t *b = (const uint8_t *)ba; sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", b[5], b[4], b[3], b[2], b[1], b[0]); } +#endif + BluetoothUnixSocketConnector::BluetoothUnixSocketConnector( BluetoothSocketType aType, int aChannel, bool aAuth, bool aEncrypt) : mType(aType) , mChannel(aChannel) , mAuth(aAuth) , mEncrypt(aEncrypt) { } bool BluetoothUnixSocketConnector::SetUp(int aFd) { +#ifdef MOZ_B2G_BT_BLUEZ int lm = 0; int sndbuf, rcvbuf; /* kernel does not yet support LM for SCO */ switch (mType) { case BluetoothSocketType::RFCOMM: lm |= mAuth ? RFCOMM_LM_AUTH : 0; lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0; @@ -152,26 +157,27 @@ BluetoothUnixSocketConnector::SetUp(int rcvbuf = L2CAP_SO_RCVBUF; if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf))) { BT_WARNING("setsockopt(SO_RCVBUF) failed, throwing"); return false; } } } - +#endif return true; } int BluetoothUnixSocketConnector::Create() { MOZ_ASSERT(!NS_IsMainThread()); int fd = -1; +#ifdef MOZ_B2G_BT_BLUEZ switch (mType) { case BluetoothSocketType::RFCOMM: fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); break; case BluetoothSocketType::SCO: fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); break; case BluetoothSocketType::L2CAP: @@ -188,26 +194,27 @@ BluetoothUnixSocketConnector::Create() BT_WARNING("Could not open bluetooth socket!"); return -1; } if (!SetUp(fd)) { BT_WARNING("Could not set up socket!"); return -1; } - +#endif return fd; } bool BluetoothUnixSocketConnector::CreateAddr(bool aIsServer, socklen_t& aAddrSize, sockaddr_any& aAddr, const char* aAddress) { +#ifdef MOZ_B2G_BT_BLUEZ // Set to BDADDR_ANY, if it's not a server, we'll reset. bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}}; if (!aIsServer && aAddress && strlen(aAddress) > 0) { if (get_bdaddr(aAddress, &bd_address_obj)) { BT_WARNING("Can't get bluetooth address!"); return false; } @@ -237,32 +244,35 @@ BluetoothUnixSocketConnector::CreateAddr aAddrSize = sizeof(addr_sco); aAddr.sco.sco_family = AF_BLUETOOTH; memcpy(&aAddr.sco.sco_bdaddr, &bd_address_obj, sizeof(bd_address_obj)); break; default: BT_WARNING("Socket type unknown!"); return false; } +#endif return true; } void BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr) { +#ifdef MOZ_B2G_BT_BLUEZ char addr[18]; switch (mType) { case BluetoothSocketType::RFCOMM: get_bdaddr_as_string((bdaddr_t*)(&aAddr.rc.rc_bdaddr), addr); break; case BluetoothSocketType::SCO: get_bdaddr_as_string((bdaddr_t*)(&aAddr.sco.sco_bdaddr), addr); break; case BluetoothSocketType::L2CAP: case BluetoothSocketType::EL2CAP: get_bdaddr_as_string((bdaddr_t*)(&aAddr.l2.l2_bdaddr), addr); break; default: MOZ_CRASH("Socket should be either RFCOMM or SCO!"); } aAddrStr.AssignASCII(addr); +#endif }
--- a/dom/bluetooth/Makefile.in +++ b/dom/bluetooth/Makefile.in @@ -31,16 +31,24 @@ ifdef MOZ_ENABLE_DBUS VPATH += $(srcdir)/linux LOCAL_INCLUDES += $(MOZ_DBUS_CFLAGS) CFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) CXXFLAGS += $(MOZ_DBUS_GLIB_CFLAGS) -DHAVE_PTHREADS DEFINES += -DMOZ_BLUETOOTH_DBUS endif endif +ifdef MOZ_B2G_BT_BLUEZ +DEFINES += -DMOZ_B2G_BT_BLUEZ +endif + +ifdef MOZ_B2G_BT_BLUEDROID +DEFINES += -DMOZ_B2G_BT_BLUEDROID +endif + # Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend # subdirectory. LOCAL_INCLUDES += $(VPATH:%=-I%) endif # MOZ_B2G_BT include $(topsrcdir)/config/rules.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk
--- a/dom/bluetooth/linux/BluetoothDBusService.h +++ b/dom/bluetooth/linux/BluetoothDBusService.h @@ -19,16 +19,19 @@ BEGIN_BLUETOOTH_NAMESPACE /** * BluetoothDBusService is the implementation of BluetoothService for DBus on * linux/android/B2G. Function comments are in BluetoothService.h */ class BluetoothDBusService : public BluetoothService { public: + BluetoothDBusService(); + ~BluetoothDBusService(); + bool IsReady(); virtual nsresult StartInternal() MOZ_OVERRIDE; virtual nsresult StopInternal() MOZ_OVERRIDE; virtual bool IsEnabledInternal() MOZ_OVERRIDE; @@ -163,21 +166,16 @@ public: virtual nsresult SendSinkMessage(const nsAString& aDeviceAddresses, const nsAString& aMessage) MOZ_OVERRIDE; virtual nsresult SendInputMessage(const nsAString& aDeviceAddresses, const nsAString& aMessage) MOZ_OVERRIDE; - -protected: - BluetoothDBusService(); - ~BluetoothDBusService(); - private: /** * For DBus Control method of "UpdateNotification", event id should be * specified as following: * (Please see specification of AVRCP 1.3, Table 5.28 for more details.) */ enum ControlEventId { EVENT_PLAYBACK_STATUS_CHANGED = 0x01,
--- a/dom/bluetooth/moz.build +++ b/dom/bluetooth/moz.build @@ -48,24 +48,29 @@ if CONFIG['MOZ_B2G_BT']: ] if CONFIG['MOZ_B2G_RIL']: CPP_SOURCES += [ 'BluetoothRilListener.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - CPP_SOURCES += [ - 'linux/BluetoothDBusService.cpp', - 'gonk/BluetoothGonkService.cpp', - ] + if CONFIG['MOZ_B2G_BT_BLUEZ']: + CPP_SOURCES += [ + 'linux/BluetoothDBusService.cpp', + 'gonk/BluetoothGonkService.cpp', + ] + if CONFIG['MOZ_B2G_BT_BLUEDROID']: + CPP_SOURCES += [ + 'BluetoothServiceBluedroid.cpp', + ] else: if CONFIG['MOZ_ENABLE_DBUS']: CPP_SOURCES += [ - 'linux/BluetoothDBusService.cpp', + 'linux/BluetoothDBusService.cpp', ] EXPORTS.mozilla.dom.bluetooth.ipc += [ 'ipc/BluetoothMessageUtils.h', ] EXPORTS.mozilla.dom.bluetooth += [ 'BluetoothCommon.h',
--- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -2,20 +2,20 @@ /* vim: set sw=4 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_tabs_TabParent_h #define mozilla_tabs_TabParent_h +#include "mozilla/EventForwards.h" #include "mozilla/dom/PBrowserParent.h" #include "mozilla/dom/PContentDialogParent.h" #include "mozilla/dom/TabContext.h" -#include "mozilla/TouchEvents.h" #include "nsCOMPtr.h" #include "nsIAuthPromptProvider.h" #include "nsIBrowserDOMWindow.h" #include "nsIDialogParamBlock.h" #include "nsISecureBrowserUI.h" #include "nsITabParent.h" #include "Units.h" #include "js/TypeDecls.h"
--- a/dom/network/interfaces/nsIMobileConnectionProvider.idl +++ b/dom/network/interfaces/nsIMobileConnectionProvider.idl @@ -28,84 +28,60 @@ interface nsIMobileConnectionListener : in unsigned long timeoutMs); void notifyOtaStatusChanged(in DOMString status); }; /** * XPCOM component (in the content process) that provides the mobile * network information. */ -[scriptable, uuid(84278a49-0f05-4585-b3f4-c74882ae5719)] +[scriptable, uuid(c66652e0-0628-11e3-8ffd-0800200c9a66)] interface nsIMobileConnectionProvider : nsISupports { /** * Called when a content process registers receiving unsolicited messages from * RadioInterfaceLayer in the chrome process. Only a content process that has * the 'mobileconnection' permission is allowed to register. */ - void registerMobileConnectionMsg(in unsigned long clientId, - in nsIMobileConnectionListener listener); - void unregisterMobileConnectionMsg(in unsigned long clientId, - in nsIMobileConnectionListener listener); - - nsIDOMMozMobileConnectionInfo getVoiceConnectionInfo(in unsigned long clientId); - nsIDOMMozMobileConnectionInfo getDataConnectionInfo(in unsigned long clientId); - DOMString getIccId(in unsigned long clientId); - DOMString getNetworkSelectionMode(in unsigned long clientId); + void registerMobileConnectionMsg(in nsIMobileConnectionListener listener); + void unregisterMobileConnectionMsg(in nsIMobileConnectionListener listener); - nsIDOMDOMRequest getNetworks(in unsigned long clientId, - in nsIDOMWindow window); - nsIDOMDOMRequest selectNetwork(in unsigned long clientId, - in nsIDOMWindow window, - in nsIDOMMozMobileNetworkInfo network); - nsIDOMDOMRequest selectNetworkAutomatically(in unsigned long clientId, - in nsIDOMWindow window); + readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo; + readonly attribute nsIDOMMozMobileConnectionInfo dataConnectionInfo; + readonly attribute DOMString networkSelectionMode; - nsIDOMDOMRequest setRoamingPreference(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest getNetworks(in nsIDOMWindow window); + nsIDOMDOMRequest selectNetwork(in nsIDOMWindow window, in nsIDOMMozMobileNetworkInfo network); + nsIDOMDOMRequest selectNetworkAutomatically(in nsIDOMWindow window); + + nsIDOMDOMRequest setRoamingPreference(in nsIDOMWindow window, in DOMString mode); - nsIDOMDOMRequest getRoamingPreference(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest getRoamingPreference(in nsIDOMWindow window); - nsIDOMDOMRequest setVoicePrivacyMode(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest setVoicePrivacyMode(in nsIDOMWindow window, in bool enabled); - nsIDOMDOMRequest getVoicePrivacyMode(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest getVoicePrivacyMode(in nsIDOMWindow window); - nsIDOMDOMRequest sendMMI(in unsigned long clientId, - in nsIDOMWindow window, - in DOMString mmi); - nsIDOMDOMRequest cancelMMI(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest sendMMI(in nsIDOMWindow window, in DOMString mmi); + nsIDOMDOMRequest cancelMMI(in nsIDOMWindow window); - nsIDOMDOMRequest getCallForwardingOption(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest getCallForwardingOption(in nsIDOMWindow window, in unsigned short reason); - nsIDOMDOMRequest setCallForwardingOption(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest setCallForwardingOption(in nsIDOMWindow window, in nsIDOMMozMobileCFInfo CFInfo); - nsIDOMDOMRequest getCallBarringOption(in unsigned long clientId, - in nsIDOMWindow window, - in jsval option); - nsIDOMDOMRequest setCallBarringOption(in unsigned long clientId, - in nsIDOMWindow window, - in jsval option); - nsIDOMDOMRequest changeCallBarringPassword(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest getCallBarringOption(in nsIDOMWindow window, + in jsval option); + nsIDOMDOMRequest setCallBarringOption(in nsIDOMWindow window, + in jsval option); + nsIDOMDOMRequest changeCallBarringPassword(in nsIDOMWindow window, in jsval info); - nsIDOMDOMRequest setCallWaitingOption(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest setCallWaitingOption(in nsIDOMWindow window, in bool enabled); - nsIDOMDOMRequest getCallWaitingOption(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest getCallWaitingOption(in nsIDOMWindow window); - nsIDOMDOMRequest setCallingLineIdRestriction(in unsigned long clientId, - in nsIDOMWindow window, + nsIDOMDOMRequest setCallingLineIdRestriction(in nsIDOMWindow window, in unsigned short clirMode); - nsIDOMDOMRequest getCallingLineIdRestriction(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest getCallingLineIdRestriction(in nsIDOMWindow window); - nsIDOMDOMRequest exitEmergencyCbMode(in unsigned long clientId, - in nsIDOMWindow window); + nsIDOMDOMRequest exitEmergencyCbMode(in nsIDOMWindow window); };
--- a/dom/network/src/MobileConnection.cpp +++ b/dom/network/src/MobileConnection.cpp @@ -78,19 +78,16 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange) NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange) MobileConnection::MobileConnection() { mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID); mWindow = nullptr; - // TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards - mClientId = 0; - // Not being able to acquire the provider isn't fatal since we check // for it explicitly below. if (!mProvider) { NS_WARNING("Could not acquire nsIMobileConnectionProvider!"); return; } } @@ -99,30 +96,30 @@ MobileConnection::Init(nsPIDOMWindow* aW { BindToOwner(aWindow); mWindow = do_GetWeakReference(aWindow); mListener = new Listener(this); if (!CheckPermission("mobilenetwork") && CheckPermission("mobileconnection")) { - DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener); + DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mListener); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed registering mobile connection messages with provider"); printf_stderr("MobileConnection initialized"); } } void MobileConnection::Shutdown() { if (mProvider && mListener) { mListener->Disconnect(); - mProvider->UnregisterMobileConnectionMsg(mClientId, mListener); + mProvider->UnregisterMobileConnectionMsg(mListener); mProvider = nullptr; mListener = nullptr; } } // nsIDOMMozMobileConnection NS_IMETHODIMP @@ -171,347 +168,347 @@ MobileConnection::CheckPermission(const NS_IMETHODIMP MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice) { *voice = nullptr; if (!mProvider || !CheckPermission("mobileconnection")) { return NS_OK; } - return mProvider->GetVoiceConnectionInfo(mClientId, voice); + return mProvider->GetVoiceConnectionInfo(voice); } NS_IMETHODIMP MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data) { *data = nullptr; if (!mProvider || !CheckPermission("mobileconnection")) { return NS_OK; } - return mProvider->GetDataConnectionInfo(mClientId, data); + return mProvider->GetDataConnectionInfo(data); } NS_IMETHODIMP MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode) { networkSelectionMode.SetIsVoid(true); if (!mProvider || !CheckPermission("mobileconnection")) { return NS_OK; } - return mProvider->GetNetworkSelectionMode(mClientId, networkSelectionMode); + return mProvider->GetNetworkSelectionMode(networkSelectionMode); } NS_IMETHODIMP MobileConnection::GetNetworks(nsIDOMDOMRequest** request) { *request = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetNetworks(mClientId, GetOwner(), request); + return mProvider->GetNetworks(GetOwner(), request); } NS_IMETHODIMP MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRequest** request) { *request = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SelectNetwork(mClientId, GetOwner(), network, request); + return mProvider->SelectNetwork(GetOwner(), network, request); } NS_IMETHODIMP MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request) { *request = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), request); + return mProvider->SelectNetworkAutomatically(GetOwner(), request); } NS_IMETHODIMP MobileConnection::SetRoamingPreference(const nsAString& aMode, nsIDOMDOMRequest** aDomRequest) { *aDomRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetRoamingPreference(mClientId, GetOwner(), aMode, aDomRequest); + return mProvider->SetRoamingPreference(GetOwner(), aMode, aDomRequest); } NS_IMETHODIMP MobileConnection::GetRoamingPreference(nsIDOMDOMRequest** aDomRequest) { *aDomRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetRoamingPreference(mClientId, GetOwner(), aDomRequest); + return mProvider->GetRoamingPreference(GetOwner(), aDomRequest); } NS_IMETHODIMP MobileConnection::SetVoicePrivacyMode(bool aEnabled, nsIDOMDOMRequest** aDomRequest) { *aDomRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled, aDomRequest); + return mProvider->SetVoicePrivacyMode(GetOwner(), aEnabled, aDomRequest); } NS_IMETHODIMP MobileConnection::GetVoicePrivacyMode(nsIDOMDOMRequest** aDomRequest) { *aDomRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetVoicePrivacyMode(mClientId, GetOwner(), aDomRequest); + return mProvider->GetVoicePrivacyMode(GetOwner(), aDomRequest); } NS_IMETHODIMP MobileConnection::SendMMI(const nsAString& aMMIString, nsIDOMDOMRequest** aRequest) { if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SendMMI(mClientId, GetOwner(), aMMIString, aRequest); + return mProvider->SendMMI(GetOwner(), aMMIString, aRequest); } NS_IMETHODIMP MobileConnection::CancelMMI(nsIDOMDOMRequest** aRequest) { if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->CancelMMI(mClientId, GetOwner(),aRequest); + return mProvider->CancelMMI(GetOwner(), aRequest); } NS_IMETHODIMP MobileConnection::GetCallForwardingOption(uint16_t aReason, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetCallForwardingOption(mClientId, GetOwner(), aReason, aRequest); + return mProvider->GetCallForwardingOption(GetOwner(), aReason, aRequest); } NS_IMETHODIMP MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest); + return mProvider->SetCallForwardingOption(GetOwner(), aCFInfo, aRequest); } NS_IMETHODIMP MobileConnection::GetCallBarringOption(const JS::Value& aOption, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest); + return mProvider->GetCallBarringOption(GetOwner(), aOption, aRequest); } NS_IMETHODIMP MobileConnection::SetCallBarringOption(const JS::Value& aOption, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest); + return mProvider->SetCallBarringOption(GetOwner(), aOption, aRequest); } NS_IMETHODIMP MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->ChangeCallBarringPassword(mClientId, GetOwner(), aInfo, aRequest); + return mProvider->ChangeCallBarringPassword(GetOwner(), aInfo, aRequest); } NS_IMETHODIMP MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetCallWaitingOption(mClientId, GetOwner(), aRequest); + return mProvider->GetCallWaitingOption(GetOwner(), aRequest); } NS_IMETHODIMP MobileConnection::SetCallWaitingOption(bool aEnabled, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetCallWaitingOption(mClientId, GetOwner(), aEnabled, aRequest); + return mProvider->SetCallWaitingOption(GetOwner(), aEnabled, aRequest); } NS_IMETHODIMP MobileConnection::GetCallingLineIdRestriction(nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(), aRequest); + return mProvider->GetCallingLineIdRestriction(GetOwner(), aRequest); } NS_IMETHODIMP MobileConnection::SetCallingLineIdRestriction(unsigned short aClirMode, nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->SetCallingLineIdRestriction(mClientId, GetOwner(), aClirMode, aRequest); + return mProvider->SetCallingLineIdRestriction(GetOwner(), aClirMode, aRequest); } NS_IMETHODIMP MobileConnection::ExitEmergencyCbMode(nsIDOMDOMRequest** aRequest) { *aRequest = nullptr; if (!CheckPermission("mobileconnection")) { return NS_OK; } if (!mProvider) { return NS_ERROR_FAILURE; } - return mProvider->ExitEmergencyCbMode(mClientId, GetOwner(), aRequest); + return mProvider->ExitEmergencyCbMode(GetOwner(), aRequest); } // nsIMobileConnectionListener NS_IMETHODIMP MobileConnection::NotifyVoiceChanged() { if (!CheckPermission("mobileconnection")) {
--- a/dom/network/src/MobileConnection.h +++ b/dom/network/src/MobileConnection.h @@ -43,18 +43,16 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileConnection, nsDOMEventTargetHelper) private: nsCOMPtr<nsIMobileConnectionProvider> mProvider; nsRefPtr<Listener> mListener; nsWeakPtr mWindow; - uint32_t mClientId; - bool CheckPermission(const char* type); }; } // namespace network } // namespace dom } // namespace mozilla #endif // mozilla_dom_network_MobileConnection_h
--- a/dom/phonenumberutils/PhoneNumberUtils.jsm +++ b/dom/phonenumberutils/PhoneNumberUtils.jsm @@ -39,18 +39,17 @@ this.PhoneNumberUtils = { _mcc: '724', getCountryName: function getCountryName() { let mcc; let countryName; #ifdef MOZ_B2G_RIL // Get network mcc - // TODO: Bug 926740 - PhoneNumberUtils for multisim - let voice = mobileConnection.getVoiceConnectionInfo(0); + let voice = mobileConnection.voiceConnectionInfo; if (voice && voice.network && voice.network.mcc) { mcc = voice.network.mcc; } // Get SIM mcc let iccInfo = icc.iccInfo; if (!mcc && iccInfo && iccInfo.mcc) { mcc = iccInfo.mcc;
--- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -83,23 +83,23 @@ const RIL_IPC_MSG_NAMES = [ "RIL:CardLockResult", "RIL:CardLockRetryCount", "RIL:USSDReceived", "RIL:SendMMI", "RIL:CancelMMI", "RIL:StkCommand", "RIL:StkSessionEnd", "RIL:DataError", - "RIL:SetCallForwardingOptions", - "RIL:GetCallForwardingOptions", - "RIL:SetCallBarringOptions", - "RIL:GetCallBarringOptions", + "RIL:SetCallForwardingOption", + "RIL:GetCallForwardingOption", + "RIL:SetCallBarringOption", + "RIL:GetCallBarringOption", "RIL:ChangeCallBarringPassword", - "RIL:SetCallWaitingOptions", - "RIL:GetCallWaitingOptions", + "RIL:SetCallWaitingOption", + "RIL:GetCallWaitingOption", "RIL:SetCallingLineIdRestriction", "RIL:GetCallingLineIdRestriction", "RIL:CellBroadcastReceived", "RIL:CfStateChanged", "RIL:IccOpenChannel", "RIL:IccCloseChannel", "RIL:IccExchangeAPDU", "RIL:ReadIccContacts", @@ -379,23 +379,23 @@ CellBroadcastEtwsInfo.prototype = { // nsIDOMMozCellBroadcastEtwsInfo warningType: null, emergencyUserAlert: null, popup: null }; -function CallBarringOptions(options) { - this.program = options.program; - this.enabled = options.enabled; - this.password = options.password; - this.serviceClass = options.serviceClass; +function CallBarringOption(option) { + this.program = option.program; + this.enabled = option.enabled; + this.password = option.password; + this.serviceClass = option.serviceClass; } -CallBarringOptions.prototype = { +CallBarringOption.prototype = { __exposedProps__ : {program: 'r', enabled: 'r', password: 'r', serviceClass: 'r'} }; function DOMMMIResult(result) { this.serviceCode = result.serviceCode; @@ -444,40 +444,27 @@ IccCardLockError.prototype = { __init: function(lockType, errorMsg, retryCount) { this.__DOM_IMPL__.init(errorMsg); this.lockType = lockType; this.retryCount = retryCount; }, }; function RILContentHelper() { - - this.numClients = gNumRadioInterfaces; - debug("Number of clients: " + this.numClients); - - this.rilContexts = []; - for (let clientId = 0; clientId < this.numClients; clientId++) { - this.rilContexts[clientId] = { - cardState: RIL.GECKO_CARDSTATE_UNKNOWN, - networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN, - iccInfo: null, - voiceConnectionInfo: new MobileConnectionInfo(), - dataConnectionInfo: new MobileConnectionInfo() - }; - } + this.rilContext = { + cardState: RIL.GECKO_CARDSTATE_UNKNOWN, + networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN, + iccInfo: null, + voiceConnectionInfo: new MobileConnectionInfo(), + dataConnectionInfo: new MobileConnectionInfo() + }; this.voicemailInfo = new VoicemailInfo(); this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES); this._windowsMap = []; - this._selectingNetworks = []; - this._mobileConnectionListeners = []; - this._cellBroadcastListeners = []; - this._voicemailListeners = []; - this._iccListeners = []; - Services.obs.addObserver(this, "xpcom-shutdown", false); } RILContentHelper.prototype = { __proto__: DOMRequestIpcHelper.prototype, QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionProvider, Ci.nsICellBroadcastProvider, @@ -533,138 +520,123 @@ RILContentHelper.prototype = { this.updateInfo(srcNetwork, network); }, /** * We need to consider below cases when update iccInfo: * 1. Should clear iccInfo to null if there is no card detected. * 2. Need to create corresponding object based on iccType. */ - updateIccInfo: function updateIccInfo(clientId, newInfo) { - let rilContext = this.rilContexts[clientId]; - + updateIccInfo: function updateIccInfo(newInfo) { // Card is not detected, clear iccInfo to null. if (!newInfo || !newInfo.iccType) { - rilContext.iccInfo = null; + this.rilContext.iccInfo = null; return; } // If iccInfo is null, new corresponding object based on iccType. - if (!rilContext.iccInfo) { + if (!this.rilContext.iccInfo) { if (newInfo.iccType === "ruim" || newInfo.iccType === "csim") { - rilContext.iccInfo = new CdmaIccInfo(); + this.rilContext.iccInfo = new CdmaIccInfo(); } else { - rilContext.iccInfo = new GsmIccInfo(); + this.rilContext.iccInfo = new GsmIccInfo(); } } - this.updateInfo(newInfo, rilContext.iccInfo); + this.updateInfo(newInfo, this.rilContext.iccInfo); }, _windowsMap: null, - rilContexts: null, + rilContext: null, - getRilContext: function getRilContext(clientId) { - // Update ril contexts by sending IPC message to chrome only when the first + getRilContext: function getRilContext() { + // Update ril context by sending IPC message to chrome only when the first // time we require it. The information will be updated by following info // changed messages. - this.getRilContext = function getRilContext(clientId) { - return this.rilContexts[clientId]; + this.getRilContext = function getRilContext() { + return this.rilContext; }; - for (let cId = 0; cId < this.numClients; cId++) { - let rilContext = - cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: cId})[0]; - if (!rilContext) { - debug("Received null rilContext from chrome process."); - continue; - } - this.rilContexts[cId].cardState = rilContext.cardState; - this.rilContexts[cId].networkSelectionMode = rilContext.networkSelectionMode; - this.updateIccInfo(cId, rilContext.iccInfo); - this.updateConnectionInfo(rilContext.voice, this.rilContexts[cId].voiceConnectionInfo); - this.updateConnectionInfo(rilContext.data, this.rilContexts[cId].dataConnectionInfo); + let rilContext = + cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: 0})[0]; + if (!rilContext) { + debug("Received null rilContext from chrome process."); + return; } + this.rilContext.cardState = rilContext.cardState; + this.rilContext.networkSelectionMode = rilContext.networkSelectionMode; + this.updateIccInfo(rilContext.iccInfo); + this.updateConnectionInfo(rilContext.voice, this.rilContext.voiceConnectionInfo); + this.updateConnectionInfo(rilContext.data, this.rilContext.dataConnectionInfo); - return this.rilContexts[clientId]; - }, - - /** - * nsIIccProvider - */ - - get iccInfo() { - //TODO: Bug 814637 - WebIccManager API: support multiple sim cards. - let context = this.getRilContext(0); - return context && context.iccInfo; - }, - - get cardState() { - //TODO: Bug 814637 - WebIccManager API: support multiple sim cards. - let context = this.getRilContext(0); - return context && context.cardState; + return this.rilContext; }, /** * nsIMobileConnectionProvider */ - getVoiceConnectionInfo: function getVoiceConnectionInfo(clientId) { - let context = this.getRilContext(clientId); + get iccInfo() { + let context = this.getRilContext(); + return context && context.iccInfo; + }, + + get voiceConnectionInfo() { + let context = this.getRilContext(); return context && context.voiceConnectionInfo; }, - getDataConnectionInfo: function getDataConnectionInfo(clientId) { - let context = this.getRilContext(clientId); + get dataConnectionInfo() { + let context = this.getRilContext(); return context && context.dataConnectionInfo; }, - getIccId: function getIccId(clientId) { - let context = this.getRilContext(clientId); - return context && context.iccInfo.iccid; + get cardState() { + let context = this.getRilContext(); + return context && context.cardState; }, - getNetworkSelectionMode: function getNetworkSelectionMode(clientId) { - let context = this.getRilContext(clientId); + get networkSelectionMode() { + let context = this.getRilContext(); return context && context.networkSelectionMode; }, /** - * The networks that are currently trying to be selected (or "automatic"). - * This helps ensure that only one network per client is selected at a time. + * The network that is currently trying to be selected (or "automatic"). + * This helps ensure that only one network is selected at a time. */ - _selectingNetworks: null, + _selectingNetwork: null, - getNetworks: function getNetworks(clientId, window) { + getNetworks: function getNetworks(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:GetAvailableNetworks", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, - selectNetwork: function selectNetwork(clientId, window, network) { + selectNetwork: function selectNetwork(window, network) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } - if (this._selectingNetworks[clientId]) { - throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]); + if (this._selectingNetwork) { + throw new Error("Already selecting a network: " + this._selectingNetwork); } if (!network) { throw new Error("Invalid network provided: " + network); } if (isNaN(parseInt(network.mnc, 10))) { throw new Error("Invalid network MNC: " + network.mnc); @@ -672,143 +644,143 @@ RILContentHelper.prototype = { if (isNaN(parseInt(network.mcc, 10))) { throw new Error("Invalid network MCC: " + network.mcc); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); - if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL && - this.rilContexts[clientId].voiceConnectionInfo.network === network) { + if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL && + this.rilContext.voiceConnectionInfo.network === network) { // Already manually selected this network, so schedule // onsuccess to be fired on the next tick this.dispatchFireRequestSuccess(requestId, null); return request; } - this._selectingNetworks[clientId] = network; + this._selectingNetwork = network; cpmm.sendAsyncMessage("RIL:SelectNetwork", { - clientId: clientId, + clientId: 0, data: { requestId: requestId, mnc: network.mnc, mcc: network.mcc } }); return request; }, - selectNetworkAutomatically: function selectNetworkAutomatically(clientId, window) { + selectNetworkAutomatically: function selectNetworkAutomatically(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } - if (this._selectingNetworks[clientId]) { - throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]); + if (this._selectingNetwork) { + throw new Error("Already selecting a network: " + this._selectingNetwork); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); - if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) { + if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) { // Already using automatic selection mode, so schedule // onsuccess to be be fired on the next tick this.dispatchFireRequestSuccess(requestId, null); return request; } - this._selectingNetworks[clientId] = "automatic"; + this._selectingNetwork = "automatic"; cpmm.sendAsyncMessage("RIL:SelectNetworkAuto", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, - setRoamingPreference: function setRoamingPreference(clientId, window, mode) { + setRoamingPreference: function setRoamingPreference(window, mode) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); if (!mode) { this.dispatchFireRequestError(requestId, RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } cpmm.sendAsyncMessage("RIL:SetRoamingPreference", { - clientId: clientId, + clientId: 0, data: { requestId: requestId, mode: mode } }); return request; }, - getRoamingPreference: function getRoamingPreference(clientId, window) { + getRoamingPreference: function getRoamingPreference(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:GetRoamingPreference", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, - setVoicePrivacyMode: function setVoicePrivacyMode(clientId, window, enabled) { + setVoicePrivacyMode: function setVoicePrivacyMode(window, enabled) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:SetVoicePrivacyMode", { - clientId: clientId, + clientId: 0, data: { requestId: requestId, enabled: enabled } }); return request; }, - getVoicePrivacyMode: function getVoicePrivacyMode(clientId, window) { + getVoicePrivacyMode: function getVoicePrivacyMode(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:GetVoicePrivacyMode", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, getCardLockState: function getCardLockState(window, lockType) { @@ -874,48 +846,48 @@ RILContentHelper.prototype = { data: { lockType: lockType, requestId: requestId } }); return request; }, - sendMMI: function sendMMI(clientId, window, mmi) { + sendMMI: function sendMMI(window, mmi) { debug("Sending MMI " + mmi); if (!window) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); // We need to save the global window to get the proper MMIError // constructor once we get the reply from the parent process. this._windowsMap[requestId] = window; cpmm.sendAsyncMessage("RIL:SendMMI", { - clientId: clientId, + clientId: 0, data: { mmi: mmi, requestId: requestId } }); return request; }, - cancelMMI: function cancelMMI(clientId, window) { + cancelMMI: function cancelMMI(window) { debug("Cancel MMI"); if (!window) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:CancelMMI", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, sendStkResponse: function sendStkResponse(window, command, response) { @@ -1099,128 +1071,128 @@ RILContentHelper.prototype = { contact: iccContact, pin2: pin2 } }); return request; }, - getCallForwardingOption: function getCallForwardingOption(clientId, window, reason) { + getCallForwardingOption: function getCallForwardingOption(window, reason) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); if (!this._isValidCFReason(reason)){ this.dispatchFireRequestError(requestId, RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } - cpmm.sendAsyncMessage("RIL:GetCallForwardingOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:GetCallForwardingOption", { + clientId: 0, data: { requestId: requestId, reason: reason } }); return request; }, - setCallForwardingOption: function setCallForwardingOption(clientId, window, cfInfo) { + setCallForwardingOption: function setCallForwardingOption(window, cfInfo) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); if (!cfInfo || !this._isValidCFReason(cfInfo.reason) || !this._isValidCFAction(cfInfo.action)){ this.dispatchFireRequestError(requestId, RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } - cpmm.sendAsyncMessage("RIL:SetCallForwardingOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:SetCallForwardingOption", { + clientId: 0, data: { requestId: requestId, active: cfInfo.active, action: cfInfo.action, reason: cfInfo.reason, number: cfInfo.number, timeSeconds: cfInfo.timeSeconds } }); return request; }, - getCallBarringOption: function getCallBarringOption(clientId, window, option) { + getCallBarringOption: function getCallBarringOption(window, option) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); if (DEBUG) debug("getCallBarringOption: " + JSON.stringify(option)); - if (!this._isValidCallBarringOptions(option)) { + if (!this._isValidCallBarringOption(option)) { this.dispatchFireRequestError(requestId, RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } - cpmm.sendAsyncMessage("RIL:GetCallBarringOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:GetCallBarringOption", { + clientId: 0, data: { requestId: requestId, program: option.program, password: option.password, serviceClass: option.serviceClass } }); return request; }, - setCallBarringOption: function setCallBarringOption(clientId, window, option) { + setCallBarringOption: function setCallBarringOption(window, option) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); if (DEBUG) debug("setCallBarringOption: " + JSON.stringify(option)); - if (!this._isValidCallBarringOptions(option, true)) { + if (!this._isValidCallBarringOption(option, true)) { this.dispatchFireRequestError(requestId, RIL.GECKO_ERROR_INVALID_PARAMETER); return request; } - cpmm.sendAsyncMessage("RIL:SetCallBarringOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:SetCallBarringOption", { + clientId: 0, data: { requestId: requestId, program: option.program, enabled: option.enabled, password: option.password, serviceClass: option.serviceClass } }); return request; }, - changeCallBarringPassword: function changeCallBarringPassword(clientId, window, info) { + changeCallBarringPassword: function changeCallBarringPassword(window, info) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); // Checking valid PIN for supplementary services. See TS.22.004 clause 5.2. @@ -1228,109 +1200,109 @@ RILContentHelper.prototype = { info.newPin == null || !info.newPin.match(/^\d{4}$/)) { this.dispatchFireRequestError(requestId, "InvalidPassword"); return request; } if (DEBUG) debug("changeCallBarringPassword: " + JSON.stringify(info)); info.requestId = requestId; cpmm.sendAsyncMessage("RIL:ChangeCallBarringPassword", { - clientId: clientId, + clientId: 0, data: info }); return request; }, - getCallWaitingOption: function getCallWaitingOption(clientId, window) { + getCallWaitingOption: function getCallWaitingOption(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); - cpmm.sendAsyncMessage("RIL:GetCallWaitingOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:GetCallWaitingOption", { + clientId: 0, data: { requestId: requestId } }); return request; }, - setCallWaitingOption: function setCallWaitingOption(clientId, window, enabled) { + setCallWaitingOption: function setCallWaitingOption(window, enabled) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); - cpmm.sendAsyncMessage("RIL:SetCallWaitingOptions", { - clientId: clientId, + cpmm.sendAsyncMessage("RIL:SetCallWaitingOption", { + clientId: 0, data: { requestId: requestId, enabled: enabled } }); return request; }, - getCallingLineIdRestriction: function getCallingLineIdRestriction(clientId, window) { + getCallingLineIdRestriction: function getCallingLineIdRestriction(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:GetCallingLineIdRestriction", { - clientId: clientId, + clientId: 0, data: { requestId: requestId } }); return request; }, setCallingLineIdRestriction: - function setCallingLineIdRestriction(clientId, window, clirMode) { + function setCallingLineIdRestriction(window, clirMode) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:SetCallingLineIdRestriction", { - clientId: clientId, + clientId: 0, data: { requestId: requestId, clirMode: clirMode } }); return request; }, - exitEmergencyCbMode: function exitEmergencyCbMode(clientId, window) { + exitEmergencyCbMode: function exitEmergencyCbMode(window) { if (window == null) { throw Components.Exception("Can't get window object", Cr.NS_ERROR_UNEXPECTED); } let request = Services.DOMRequest.createRequest(window); let requestId = this.getRequestId(request); cpmm.sendAsyncMessage("RIL:ExitEmergencyCbMode", { - clientId: clientId, + clientId: 0, data: { requestId: requestId, } }); return request; }, @@ -1357,93 +1329,81 @@ RILContentHelper.prototype = { }, get voicemailNumber() { return this.getVoicemailInfo().number; }, get voicemailDisplayName() { return this.getVoicemailInfo().displayName; }, - registerListener: function registerListener(listenerType, clientId, listener) { - if (!this[listenerType]) { - return; - } - let listeners = this[listenerType][clientId]; + registerListener: function registerListener(listenerType, listener) { + let listeners = this[listenerType]; if (!listeners) { - listeners = this[listenerType][clientId] = []; + listeners = this[listenerType] = []; } if (listeners.indexOf(listener) != -1) { throw new Error("Already registered this listener!"); } listeners.push(listener); if (DEBUG) debug("Registered " + listenerType + " listener: " + listener); }, - unregisterListener: function unregisterListener(listenerType, clientId, listener) { - if (!this[listenerType]) { - return; - } - let listeners = this[listenerType][clientId]; + unregisterListener: function unregisterListener(listenerType, listener) { + let listeners = this[listenerType]; if (!listeners) { return; } let index = listeners.indexOf(listener); if (index != -1) { listeners.splice(index, 1); if (DEBUG) debug("Unregistered listener: " + listener); } }, - registerMobileConnectionMsg: function registerMobileConnectionMsg(clientId, listener) { + registerMobileConnectionMsg: function registerMobileConnectionMsg(listener) { debug("Registering for mobile connection related messages"); - this.registerListener("_mobileConnectionListeners", clientId, listener); + this.registerListener("_mobileConnectionListeners", listener); cpmm.sendAsyncMessage("RIL:RegisterMobileConnectionMsg"); }, - unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(clientId, listener) { - this.unregisterListener("_mobileConnectionListeners", clientId, listener); + unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(listener) { + this.unregisterListener("_mobileConnectionListeners", listener); }, registerVoicemailMsg: function registerVoicemailMsg(listener) { debug("Registering for voicemail-related messages"); - //TODO: Bug 814634 - WebVoicemail API: support multiple sim cards. - this.registerListener("_voicemailListeners", 0, listener); + this.registerListener("_voicemailListeners", listener); cpmm.sendAsyncMessage("RIL:RegisterVoicemailMsg"); }, unregisterVoicemailMsg: function unregisteVoicemailMsg(listener) { - //TODO: Bug 814634 - WebVoicemail API: support multiple sim cards. - this.unregisterListener("_voicemailListeners", 0, listener); + this.unregisterListener("_voicemailListeners", listener); }, registerCellBroadcastMsg: function registerCellBroadcastMsg(listener) { debug("Registering for Cell Broadcast related messages"); - //TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards - this.registerListener("_cellBroadcastListeners", 0, listener); + this.registerListener("_cellBroadcastListeners", listener); cpmm.sendAsyncMessage("RIL:RegisterCellBroadcastMsg"); }, unregisterCellBroadcastMsg: function unregisterCellBroadcastMsg(listener) { - //TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards - this.unregisterListener("_cellBroadcastListeners", 0, listener); + this.unregisterListener("_cellBroadcastListeners", listener); }, registerIccMsg: function registerIccMsg(listener) { debug("Registering for ICC related messages"); - //TODO: Bug 814637 - WebIccManager API: support multiple sim cards. - this.registerListener("_iccListeners", 0, listener); + this.registerListener("_iccListeners", listener); cpmm.sendAsyncMessage("RIL:RegisterIccMsg"); }, unregisterIccMsg: function unregisterIccMsg(listener) { - //TODO: Bug 814637 - WebIccManager API: support multiple sim cards. - this.unregisterListener("_iccListeners", 0, listener); + this.unregisterListener("_iccListeners", listener); }, // nsIObserver observe: function observe(subject, topic, data) { if (topic == "xpcom-shutdown") { this.destroyDOMRequestHelper(); Services.obs.removeObserver(this, "xpcom-shutdown"); @@ -1513,72 +1473,64 @@ RILContentHelper.prototype = { Services.DOMRequest.fireDetailedError(request, detailedError); }, receiveMessage: function receiveMessage(msg) { let request; debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json)); let data = msg.json.data; - let clientId = msg.json.clientId; switch (msg.name) { case "RIL:CardStateChanged": - if (this.rilContexts[clientId].cardState != data.cardState) { - this.rilContexts[clientId].cardState = data.cardState; - this._deliverEvent(clientId, - "_iccListeners", + if (this.rilContext.cardState != data.cardState) { + this.rilContext.cardState = data.cardState; + this._deliverEvent("_iccListeners", "notifyCardStateChanged", null); } break; case "RIL:IccInfoChanged": - this.updateIccInfo(clientId, data); - this._deliverEvent(clientId, - "_iccListeners", - "notifyIccInfoChanged", - null); + this.updateIccInfo(data); + this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null); break; case "RIL:VoiceInfoChanged": this.updateConnectionInfo(data, - this.rilContexts[clientId].voiceConnectionInfo); - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this.rilContext.voiceConnectionInfo); + this._deliverEvent("_mobileConnectionListeners", "notifyVoiceChanged", null); break; case "RIL:DataInfoChanged": this.updateConnectionInfo(data, - this.rilContexts[clientId].dataConnectionInfo); - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this.rilContext.dataConnectionInfo); + this._deliverEvent("_mobileConnectionListeners", "notifyDataChanged", null); break; case "RIL:OtaStatusChanged": - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this._deliverEvent("_mobileConnectionListeners", "notifyOtaStatusChanged", [data]); break; case "RIL:GetAvailableNetworks": this.handleGetAvailableNetworks(data); break; case "RIL:NetworkSelectionModeChanged": - this.rilContexts[clientId].networkSelectionMode = data.mode; + this.rilContext.networkSelectionMode = data.mode; break; case "RIL:SelectNetwork": - this.handleSelectNetwork(clientId, data, + this.handleSelectNetwork(data, RIL.GECKO_NETWORK_SELECTION_MANUAL); break; case "RIL:SelectNetworkAuto": - this.handleSelectNetwork(clientId, data, + this.handleSelectNetwork(data, RIL.GECKO_NETWORK_SELECTION_AUTOMATIC); break; case "RIL:VoicemailNotification": - this.handleVoicemailNotification(clientId, data); + this.handleVoicemailNotification(data); break; case "RIL:VoicemailInfoChanged": this.updateInfo(data, this.voicemailInfo); break; case "RIL:CardLockResult": { let requestId = data.requestId; let requestWindow = this._windowsMap[requestId]; delete this._windowsMap[requestId]; @@ -1603,31 +1555,30 @@ RILContentHelper.prototype = { if (data.success) { let result = new MobileIccCardLockRetryCount(data); this.fireRequestSuccess(data.requestId, result); } else { this.fireRequestError(data.requestId, data.errorMsg); } break; case "RIL:USSDReceived": - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this._deliverEvent("_mobileConnectionListeners", "notifyUssdReceived", [data.message, data.sessionEnded]); break; case "RIL:SendMMI": case "RIL:CancelMMI": this.handleSendCancelMMI(data); break; case "RIL:StkCommand": - this._deliverEvent(clientId, "_iccListeners", "notifyStkCommand", + this._deliverEvent("_iccListeners", "notifyStkCommand", [JSON.stringify(data)]); break; case "RIL:StkSessionEnd": - this._deliverEvent(clientId, "_iccListeners", "notifyStkSessionEnd", null); + this._deliverEvent("_iccListeners", "notifyStkSessionEnd", null); break; case "RIL:IccOpenChannel": this.handleSimpleRequest(data.requestId, data.errorMsg, data.channel); break; case "RIL:IccCloseChannel": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; @@ -1636,77 +1587,74 @@ RILContentHelper.prototype = { break; case "RIL:ReadIccContacts": this.handleReadIccContacts(data); break; case "RIL:UpdateIccContact": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:DataError": - this.updateConnectionInfo(data, this.rilContexts[clientId].dataConnectionInfo); - this._deliverEvent(clientId, "_mobileConnectionListeners", "notifyDataError", + this.updateConnectionInfo(data, this.rilContext.dataConnectionInfo); + this._deliverEvent("_mobileConnectionListeners", "notifyDataError", [data.errorMsg]); break; - case "RIL:GetCallForwardingOptions": - this.handleGetCallForwardingOptions(data); + case "RIL:GetCallForwardingOption": + this.handleGetCallForwardingOption(data); break; - case "RIL:SetCallForwardingOptions": + case "RIL:SetCallForwardingOption": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; - case "RIL:GetCallBarringOptions": - this.handleGetCallBarringOptions(data); + case "RIL:GetCallBarringOption": + this.handleGetCallBarringOption(data); break; - case "RIL:SetCallBarringOptions": + case "RIL:SetCallBarringOption": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:ChangeCallBarringPassword": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; - case "RIL:GetCallWaitingOptions": + case "RIL:GetCallWaitingOption": this.handleSimpleRequest(data.requestId, data.errorMsg, data.enabled); break; - case "RIL:SetCallWaitingOptions": + case "RIL:SetCallWaitingOption": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:CfStateChanged": - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this._deliverEvent("_mobileConnectionListeners", "notifyCFStateChange", [data.success, data.action, data.reason, data.number, data.timeSeconds, data.serviceClass]); break; case "RIL:GetCallingLineIdRestriction": this.handleGetCallingLineIdRestriction(data); break; case "RIL:SetCallingLineIdRestriction": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:CellBroadcastReceived": { let message = new CellBroadcastMessage(data); - this._deliverEvent(clientId, - "_cellBroadcastListeners", + this._deliverEvent("_cellBroadcastListeners", "notifyMessageReceived", [message]); break; } case "RIL:SetRoamingPreference": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:GetRoamingPreference": this.handleSimpleRequest(data.requestId, data.errorMsg, data.mode); break; case "RIL:ExitEmergencyCbMode": this.handleExitEmergencyCbMode(data); break; case "RIL:EmergencyCbModeChanged": - this._deliverEvent(clientId, - "_mobileConnectionListeners", + this._deliverEvent("_mobileConnectionListeners", "notifyEmergencyCbModeChanged", [data.active, data.timeoutMs]); break; case "RIL:SetVoicePrivacyMode": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:GetVoicePrivacyMode": this.handleSimpleRequest(data.requestId, data.errorMsg, @@ -1737,19 +1685,19 @@ RILContentHelper.prototype = { let info = new MobileNetworkInfo(); this.updateInfo(network, info); networks[i] = info; } this.fireRequestSuccess(message.requestId, networks); }, - handleSelectNetwork: function handleSelectNetwork(clientId, message, mode) { - this._selectingNetworks[clientId] = null; - this.rilContexts[clientId].networkSelectionMode = mode; + handleSelectNetwork: function handleSelectNetwork(message, mode) { + this._selectingNetwork = null; + this.rilContext.networkSelectionMode = mode; if (message.errorMsg) { this.fireRequestError(message.requestId, message.errorMsg); } else { this.fireRequestSuccess(message.requestId, null); } }, @@ -1788,18 +1736,17 @@ RILContentHelper.prototype = { contact.id = message.iccid + c.recordId; return contact; }); this.fireRequestSuccess(message.requestId, ObjectWrapper.wrap(result, window)); }, - handleVoicemailNotification: function handleVoicemailNotification(clientId, message) { - // TODO: Bug 818352 - B2G Multi-SIM: voicemail - add subscription id in nsIRILContentHelper + handleVoicemailNotification: function handleVoicemailNotification(message) { let changed = false; if (!this.voicemailStatus) { this.voicemailStatus = new VoicemailStatus(); } if (this.voicemailStatus.hasMessages != message.active) { changed = true; this.voicemailStatus.hasMessages = message.active; @@ -1819,48 +1766,47 @@ RILContentHelper.prototype = { } if (this.voicemailStatus.returnMessage != message.returnMessage) { changed = true; this.voicemailStatus.returnMessage = message.returnMessage; } if (changed) { - this._deliverEvent(clientId, - "_voicemailListeners", + this._deliverEvent("_voicemailListeners", "notifyStatusChanged", [this.voicemailStatus]); } }, _cfRulesToMobileCfInfo: function _cfRulesToMobileCfInfo(rules) { for (let i = 0; i < rules.length; i++) { let rule = rules[i]; let info = new MobileCFInfo(); this.updateInfo(rule, info); rules[i] = info; } }, - handleGetCallForwardingOptions: function handleGetCallForwardingOptions(message) { + handleGetCallForwardingOption: function handleGetCallForwardingOption(message) { if (message.errorMsg) { this.fireRequestError(message.requestId, message.errorMsg); return; } this._cfRulesToMobileCfInfo(message.rules); this.fireRequestSuccess(message.requestId, message.rules); }, - handleGetCallBarringOptions: function handleGetCallBarringOptions(message) { + handleGetCallBarringOption: function handleGetCallBarringOption(message) { if (!message.success) { this.fireRequestError(message.requestId, message.errorMsg); } else { - let options = new CallBarringOptions(message); - this.fireRequestSuccess(message.requestId, options); + let option = new CallBarringOption(message); + this.fireRequestSuccess(message.requestId, option); } }, handleGetCallingLineIdRestriction: function handleGetCallingLineIdRestriction(message) { if (message.errorMsg) { this.fireRequestError(message.requestId, message.errorMsg); return; @@ -1926,21 +1872,18 @@ RILContentHelper.prototype = { let mmiError = new requestWindow.DOMMMIError(result.serviceCode, message.errorMsg, null, result.additionalInformation); Services.DOMRequest.fireDetailedError(request, mmiError); } }, - _deliverEvent: function _deliverEvent(clientId, listenerType, name, args) { - if (!this[listenerType]) { - return; - } - let thisListeners = this[listenerType][clientId]; + _deliverEvent: function _deliverEvent(listenerType, name, args) { + let thisListeners = this[listenerType]; if (!thisListeners) { return; } let listeners = thisListeners.slice(); for (let listener of listeners) { if (thisListeners.indexOf(listener) == -1) { continue; @@ -2001,28 +1944,28 @@ RILContentHelper.prototype = { case Ci.nsIDOMMozMobileConnection.CALL_BARRING_PROGRAM_INCOMING_ROAMING: return true; default: return false; } }, /** - * Helper for guarding us against invalid options for call barring. + * Helper for guarding us against invalid option for call barring. */ - _isValidCallBarringOptions: - function _isValidCallBarringOptions(options, usedForSetting) { - if (!options || - options.serviceClass == null || - !this._isValidCallBarringProgram(options.program)) { + _isValidCallBarringOption: + function _isValidCallBarringOption(option, usedForSetting) { + if (!option || + option.serviceClass == null || + !this._isValidCallBarringProgram(option.program)) { return false; } - // For setting callbarring options, |enabled| and |password| are required. - if (usedForSetting && (options.enabled == null || options.password == null)) { + // For setting callbarring option, |enabled| and |password| are required. + if (usedForSetting && (option.enabled == null || option.password == null)) { return false; } return true; } }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RILContentHelper,
--- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -85,23 +85,23 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES "RIL:GetNumRadioInterfaces", "RIL:GetRilContext", "RIL:GetAvailableNetworks", "RIL:SelectNetwork", "RIL:SelectNetworkAuto", "RIL:SendMMI", "RIL:CancelMMI", "RIL:RegisterMobileConnectionMsg", - "RIL:SetCallForwardingOptions", - "RIL:GetCallForwardingOptions", - "RIL:SetCallBarringOptions", - "RIL:GetCallBarringOptions", + "RIL:SetCallForwardingOption", + "RIL:GetCallForwardingOption", + "RIL:SetCallBarringOption", + "RIL:GetCallBarringOption", "RIL:ChangeCallBarringPassword", - "RIL:SetCallWaitingOptions", - "RIL:GetCallWaitingOptions", + "RIL:SetCallWaitingOption", + "RIL:GetCallWaitingOption", "RIL:SetCallingLineIdRestriction", "RIL:GetCallingLineIdRestriction", "RIL:SetRoamingPreference", "RIL:GetRoamingPreference", "RIL:ExitEmergencyCbMode", "RIL:SetVoicePrivacyMode", "RIL:GetVoicePrivacyMode" ]; @@ -930,35 +930,35 @@ RadioInterface.prototype = { this.workerMessenger.sendWithIPCMessage(msg, "iccExchangeAPDU"); break; case "RIL:ReadIccContacts": this.workerMessenger.sendWithIPCMessage(msg, "readICCContacts"); break; case "RIL:UpdateIccContact": this.workerMessenger.sendWithIPCMessage(msg, "updateICCContact"); break; - case "RIL:SetCallForwardingOptions": - this.setCallForwardingOptions(msg.target, msg.json.data); + case "RIL:SetCallForwardingOption": + this.setCallForwardingOption(msg.target, msg.json.data); break; - case "RIL:GetCallForwardingOptions": + case "RIL:GetCallForwardingOption": this.workerMessenger.sendWithIPCMessage(msg, "queryCallForwardStatus"); break; - case "RIL:SetCallBarringOptions": + case "RIL:SetCallBarringOption": this.workerMessenger.sendWithIPCMessage(msg, "setCallBarring"); break; - case "RIL:GetCallBarringOptions": + case "RIL:GetCallBarringOption": this.workerMessenger.sendWithIPCMessage(msg, "queryCallBarringStatus"); break; case "RIL:ChangeCallBarringPassword": this.workerMessenger.sendWithIPCMessage(msg, "changeCallBarringPassword"); break; - case "RIL:SetCallWaitingOptions": + case "RIL:SetCallWaitingOption": this.workerMessenger.sendWithIPCMessage(msg, "setCallWaiting"); break; - case "RIL:GetCallWaitingOptions": + case "RIL:GetCallWaitingOption": this.workerMessenger.sendWithIPCMessage(msg, "queryCallWaiting"); break; case "RIL:SetCallingLineIdRestriction": this.setCallingLineIdRestriction(msg.target, msg.json.data); break; case "RIL:GetCallingLineIdRestriction": this.workerMessenger.sendWithIPCMessage(msg, "getCLIR"); break; @@ -2401,22 +2401,22 @@ RadioInterface.prototype = { target.sendAsyncMessage("RIL:SendMMI", { clientId: this.clientId, data: response }); return false; }).bind(this)); }, - setCallForwardingOptions: function setCallForwardingOptions(target, message) { - if (DEBUG) this.debug("setCallForwardingOptions: " + JSON.stringify(message)); + setCallForwardingOption: function setCallForwardingOption(target, message) { + if (DEBUG) this.debug("setCallForwardingOption: " + JSON.stringify(message)); message.serviceClass = RIL.ICC_SERVICE_CLASS_VOICE; this.workerMessenger.send("setCallForward", message, (function(response) { this._sendCfStateChanged(response); - target.sendAsyncMessage("RIL:SetCallForwardingOptions", { + target.sendAsyncMessage("RIL:SetCallForwardingOption", { clientId: this.clientId, data: response }); return false; }).bind(this)); }, setCallingLineIdRestriction: function setCallingLineIdRestriction(target,
--- a/dom/webidl/HTMLMediaElement.webidl +++ b/dom/webidl/HTMLMediaElement.webidl @@ -109,21 +109,21 @@ partial interface HTMLMediaElement { readonly attribute boolean mozAudioCaptured; // Mozilla extension: extra stream metadata information, used as part // of MozAudioAvailable events and the mozWriteAudio() method. The // mozFrameBufferLength method allows for the size of the framebuffer // used within MozAudioAvailable events to be changed. The new size must // be between 512 and 16384. The default size, for a media element with // audio is (mozChannels * 1024). - [GetterThrows] + [Pref="media.audio_data.enabled", GetterThrows] readonly attribute unsigned long mozChannels; - [GetterThrows] + [Pref="media.audio_data.enabled", GetterThrows] readonly attribute unsigned long mozSampleRate; - [Throws] + [Pref="media.audio_data.enabled", Throws] attribute unsigned long mozFrameBufferLength; // Mozilla extension: return embedded metadata from the stream as a // JSObject with key:value pairs for each tag. This can be used by // player interfaces to display the song title, artist, etc. [Throws] object? mozGetMetadata();
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -3,16 +3,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 <string.h> #include "mozilla/dom/DocumentFragment.h" #include "mozilla/Base64.h" +#include "mozilla/BasicEvents.h" #include "mozilla/Preferences.h" #include "mozilla/Selection.h" #include "mozilla/Util.h" #include "nsAString.h" #include "nsAutoPtr.h" #include "nsCOMArray.h" #include "nsCOMPtr.h" #include "nsCRT.h"
--- a/ipc/moz.build +++ b/ipc/moz.build @@ -9,17 +9,17 @@ DIRS += [ 'glue', 'ipdl', 'testshell', ] if CONFIG['MOZ_B2G_RIL']: DIRS += ['ril'] -if CONFIG['MOZ_B2G_BT']: +if CONFIG['MOZ_B2G_BT_BLUEZ']: DIRS += ['dbus'] if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT']: DIRS += ['unixsocket', 'keystore'] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': DIRS += ['netd']
--- a/ipc/unixsocket/UnixSocket.h +++ b/ipc/unixsocket/UnixSocket.h @@ -7,17 +7,17 @@ #ifndef mozilla_ipc_UnixSocket_h #define mozilla_ipc_UnixSocket_h #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> #include <netinet/in.h> -#ifdef MOZ_B2G_BT +#ifdef MOZ_B2G_BT_BLUEZ #include <bluetooth/bluetooth.h> #include <bluetooth/sco.h> #include <bluetooth/l2cap.h> #include <bluetooth/rfcomm.h> #endif #include <stdlib.h> #include "nsString.h" #include "nsAutoPtr.h" @@ -26,17 +26,17 @@ namespace mozilla { namespace ipc { union sockaddr_any { sockaddr_storage storage; // address-family only sockaddr_un un; sockaddr_in in; sockaddr_in6 in6; -#ifdef MOZ_B2G_BT +#ifdef MOZ_B2G_BT_BLUEZ sockaddr_sco sco; sockaddr_rc rc; sockaddr_l2 l2; #endif // ... others }; class UnixSocketRawData
--- a/js/public/MemoryMetrics.h +++ b/js/public/MemoryMetrics.h @@ -20,16 +20,47 @@ #include "jspubtd.h" #include "js/HashTable.h" #include "js/Utility.h" #include "js/Vector.h" class nsISupports; // Needed for ObjectPrivateVisitor. +namespace JS { + +struct TabSizes +{ + enum Kind { + Objects, + Strings, + Private, + Other + }; + + TabSizes() { mozilla::PodZero(this); } + + void add(Kind kind, size_t n) { + switch (kind) { + case Objects: objects += n; break; + case Strings: strings += n; break; + case Private: private_ += n; break; + case Other: other += n; break; + default: MOZ_CRASH("bad TabSizes kind"); + } + } + + size_t objects; + size_t strings; + size_t private_; + size_t other; +}; + +} // namespace JS + namespace js { // In memory reporting, we have concept of "sundries", line items which are too // small to be worth reporting individually. Under some circumstances, a memory // reporter gets tossed into the sundries bucket if it's smaller than // MemoryReportingSundriesThreshold() bytes. // // We need to define this value here, rather than in the code which actually @@ -52,42 +83,43 @@ struct InefficientNonFlatteningStringHas // without updating all the required methods. So we define a single macro list // in each class to name the fields (and notable characteristics of them), and // then use the following macros to transform those lists into the required // methods. // // In some classes, one or more of the macro arguments aren't used. We use '_' // for those. // -#define DECL_SIZE(gc, mSize) size_t mSize; -#define ZERO_SIZE(gc, mSize) mSize(0), -#define COPY_OTHER_SIZE(gc, mSize) mSize(other.mSize), -#define ADD_OTHER_SIZE(gc, mSize) mSize += other.mSize; -#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(gc, mSize) n += (gc) ? mSize : 0; +#define DECL_SIZE(kind, gc, mSize) size_t mSize; +#define ZERO_SIZE(kind, gc, mSize) mSize(0), +#define COPY_OTHER_SIZE(kind, gc, mSize) mSize(other.mSize), +#define ADD_OTHER_SIZE(kind, gc, mSize) mSize += other.mSize; +#define ADD_SIZE_TO_N_IF_LIVE_GC_THING(kind, gc, mSize) n += (js::gc == js::IsLiveGCThing) ? mSize : 0; +#define ADD_TO_TAB_SIZES(kind, gc, mSize) sizes->add(JS::TabSizes::kind, mSize); // Used to annotate which size_t fields measure live GC things and which don't. enum { NotLiveGCThing = false, IsLiveGCThing = true }; struct ZoneStatsPod { #define FOR_EACH_SIZE(macro) \ - macro(NotLiveGCThing, gcHeapArenaAdmin) \ - macro(NotLiveGCThing, unusedGCThings) \ - macro(IsLiveGCThing, lazyScriptsGCHeap) \ - macro(NotLiveGCThing, lazyScriptsMallocHeap) \ - macro(IsLiveGCThing, ionCodesGCHeap) \ - macro(IsLiveGCThing, typeObjectsGCHeap) \ - macro(NotLiveGCThing, typeObjectsMallocHeap) \ - macro(NotLiveGCThing, typePool) \ - macro(IsLiveGCThing, stringsShortGCHeap) \ - macro(IsLiveGCThing, stringsNormalGCHeap) \ - macro(NotLiveGCThing, stringsNormalMallocHeap) + macro(Other, NotLiveGCThing, gcHeapArenaAdmin) \ + macro(Other, NotLiveGCThing, unusedGCThings) \ + macro(Other, IsLiveGCThing, lazyScriptsGCHeap) \ + macro(Other, NotLiveGCThing, lazyScriptsMallocHeap) \ + macro(Other, IsLiveGCThing, ionCodesGCHeap) \ + macro(Other, IsLiveGCThing, typeObjectsGCHeap) \ + macro(Other, NotLiveGCThing, typeObjectsMallocHeap) \ + macro(Other, NotLiveGCThing, typePool) \ + macro(Strings, IsLiveGCThing, stringsShortGCHeap) \ + macro(Strings, IsLiveGCThing, stringsNormalGCHeap) \ + macro(Strings, NotLiveGCThing, stringsNormalMallocHeap) ZoneStatsPod() : FOR_EACH_SIZE(ZERO_SIZE) extra() {} void add(const ZoneStatsPod &other) { FOR_EACH_SIZE(ADD_OTHER_SIZE) @@ -96,71 +128,80 @@ struct ZoneStatsPod size_t sizeOfLiveGCThings() const { size_t n = 0; FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) // Do nothing with |extra|. return n; } + void addToTabSizes(JS::TabSizes *sizes) const { + FOR_EACH_SIZE(ADD_TO_TAB_SIZES) + // Do nothing with |extra|. + } + FOR_EACH_SIZE(DECL_SIZE) void *extra; // This field can be used by embedders. #undef FOR_EACH_SIZE }; } // namespace js namespace JS { // Data for tracking memory usage of things hanging off objects. struct ObjectsExtraSizes { #define FOR_EACH_SIZE(macro) \ - macro(js::NotLiveGCThing, mallocHeapSlots) \ - macro(js::NotLiveGCThing, mallocHeapElementsNonAsmJS) \ - macro(js::NotLiveGCThing, mallocHeapElementsAsmJS) \ - macro(js::NotLiveGCThing, nonHeapElementsAsmJS) \ - macro(js::NotLiveGCThing, nonHeapCodeAsmJS) \ - macro(js::NotLiveGCThing, mallocHeapAsmJSModuleData) \ - macro(js::NotLiveGCThing, mallocHeapArgumentsData) \ - macro(js::NotLiveGCThing, mallocHeapRegExpStatics) \ - macro(js::NotLiveGCThing, mallocHeapPropertyIteratorData) \ - macro(js::NotLiveGCThing, mallocHeapCtypesData) + macro(Objects, NotLiveGCThing, mallocHeapSlots) \ + macro(Objects, NotLiveGCThing, mallocHeapElementsNonAsmJS) \ + macro(Objects, NotLiveGCThing, mallocHeapElementsAsmJS) \ + macro(Objects, NotLiveGCThing, nonHeapElementsAsmJS) \ + macro(Objects, NotLiveGCThing, nonHeapCodeAsmJS) \ + macro(Objects, NotLiveGCThing, mallocHeapAsmJSModuleData) \ + macro(Objects, NotLiveGCThing, mallocHeapArgumentsData) \ + macro(Objects, NotLiveGCThing, mallocHeapRegExpStatics) \ + macro(Objects, NotLiveGCThing, mallocHeapPropertyIteratorData) \ + macro(Objects, NotLiveGCThing, mallocHeapCtypesData) ObjectsExtraSizes() : FOR_EACH_SIZE(ZERO_SIZE) dummy() {} void add(const ObjectsExtraSizes &other) { FOR_EACH_SIZE(ADD_OTHER_SIZE) } size_t sizeOfLiveGCThings() const { size_t n = 0; FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) return n; } + void addToTabSizes(TabSizes *sizes) const { + FOR_EACH_SIZE(ADD_TO_TAB_SIZES) + } + FOR_EACH_SIZE(DECL_SIZE) int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) #undef FOR_EACH_SIZE }; // Data for tracking JIT-code memory usage. struct CodeSizes { #define FOR_EACH_SIZE(macro) \ - macro(_, ion) \ - macro(_, baseline) \ - macro(_, regexp) \ - macro(_, other) \ - macro(_, unused) + macro(_, _, ion) \ + macro(_, _, baseline) \ + macro(_, _, regexp) \ + macro(_, _, other) \ + macro(_, _, unused) CodeSizes() : FOR_EACH_SIZE(ZERO_SIZE) dummy() {} FOR_EACH_SIZE(DECL_SIZE) int dummy; // present just to absorb the trailing comma from FOR_EACH_SIZE(ZERO_SIZE) @@ -251,27 +292,27 @@ struct NotableStringInfo : public String char *buffer; }; // These measurements relate directly to the JSRuntime, and not to zones and // compartments within it. struct RuntimeSizes { #define FOR_EACH_SIZE(macro) \ - macro(_, object) \ - macro(_, atomsTable) \ - macro(_, contexts) \ - macro(_, dtoa) \ - macro(_, temporary) \ - macro(_, regexpData) \ - macro(_, interpreterStack) \ - macro(_, gcMarker) \ - macro(_, mathCache) \ - macro(_, scriptData) \ - macro(_, scriptSources) + macro(_, _, object) \ + macro(_, _, atomsTable) \ + macro(_, _, contexts) \ + macro(_, _, dtoa) \ + macro(_, _, temporary) \ + macro(_, _, regexpData) \ + macro(_, _, interpreterStack) \ + macro(_, _, gcMarker) \ + macro(_, _, mathCache) \ + macro(_, _, scriptData) \ + macro(_, _, scriptSources) RuntimeSizes() : FOR_EACH_SIZE(ZERO_SIZE) code() {} FOR_EACH_SIZE(DECL_SIZE) CodeSizes code; @@ -330,45 +371,45 @@ struct ZoneStats : js::ZoneStatsPod StringsHashMap strings; js::Vector<NotableStringInfo, 0, js::SystemAllocPolicy> notableStrings; }; struct CompartmentStats { #define FOR_EACH_SIZE(macro) \ - macro(js::IsLiveGCThing, objectsGCHeapOrdinary) \ - macro(js::IsLiveGCThing, objectsGCHeapFunction) \ - macro(js::IsLiveGCThing, objectsGCHeapDenseArray) \ - macro(js::IsLiveGCThing, objectsGCHeapSlowArray) \ - macro(js::IsLiveGCThing, objectsGCHeapCrossCompartmentWrapper) \ - macro(js::NotLiveGCThing, objectsPrivate) \ - macro(js::IsLiveGCThing, shapesGCHeapTreeGlobalParented) \ - macro(js::IsLiveGCThing, shapesGCHeapTreeNonGlobalParented) \ - macro(js::IsLiveGCThing, shapesGCHeapDict) \ - macro(js::IsLiveGCThing, shapesGCHeapBase) \ - macro(js::NotLiveGCThing, shapesMallocHeapTreeTables) \ - macro(js::NotLiveGCThing, shapesMallocHeapDictTables) \ - macro(js::NotLiveGCThing, shapesMallocHeapTreeShapeKids) \ - macro(js::NotLiveGCThing, shapesMallocHeapCompartmentTables) \ - macro(js::IsLiveGCThing, scriptsGCHeap) \ - macro(js::NotLiveGCThing, scriptsMallocHeapData) \ - macro(js::NotLiveGCThing, baselineData) \ - macro(js::NotLiveGCThing, baselineStubsFallback) \ - macro(js::NotLiveGCThing, baselineStubsOptimized) \ - macro(js::NotLiveGCThing, ionData) \ - macro(js::NotLiveGCThing, typeInferenceTypeScripts) \ - macro(js::NotLiveGCThing, typeInferencePendingArrays) \ - macro(js::NotLiveGCThing, typeInferenceAllocationSiteTables) \ - macro(js::NotLiveGCThing, typeInferenceArrayTypeTables) \ - macro(js::NotLiveGCThing, typeInferenceObjectTypeTables) \ - macro(js::NotLiveGCThing, compartmentObject) \ - macro(js::NotLiveGCThing, crossCompartmentWrappersTable) \ - macro(js::NotLiveGCThing, regexpCompartment) \ - macro(js::NotLiveGCThing, debuggeesSet) + macro(Objects, IsLiveGCThing, objectsGCHeapOrdinary) \ + macro(Objects, IsLiveGCThing, objectsGCHeapFunction) \ + macro(Objects, IsLiveGCThing, objectsGCHeapDenseArray) \ + macro(Objects, IsLiveGCThing, objectsGCHeapSlowArray) \ + macro(Objects, IsLiveGCThing, objectsGCHeapCrossCompartmentWrapper) \ + macro(Private, NotLiveGCThing, objectsPrivate) \ + macro(Other, IsLiveGCThing, shapesGCHeapTreeGlobalParented) \ + macro(Other, IsLiveGCThing, shapesGCHeapTreeNonGlobalParented) \ + macro(Other, IsLiveGCThing, shapesGCHeapDict) \ + macro(Other, IsLiveGCThing, shapesGCHeapBase) \ + macro(Other, NotLiveGCThing, shapesMallocHeapTreeTables) \ + macro(Other, NotLiveGCThing, shapesMallocHeapDictTables) \ + macro(Other, NotLiveGCThing, shapesMallocHeapTreeShapeKids) \ + macro(Other, NotLiveGCThing, shapesMallocHeapCompartmentTables) \ + macro(Other, IsLiveGCThing, scriptsGCHeap) \ + macro(Other, NotLiveGCThing, scriptsMallocHeapData) \ + macro(Other, NotLiveGCThing, baselineData) \ + macro(Other, NotLiveGCThing, baselineStubsFallback) \ + macro(Other, NotLiveGCThing, baselineStubsOptimized) \ + macro(Other, NotLiveGCThing, ionData) \ + macro(Other, NotLiveGCThing, typeInferenceTypeScripts) \ + macro(Other, NotLiveGCThing, typeInferencePendingArrays) \ + macro(Other, NotLiveGCThing, typeInferenceAllocationSiteTables) \ + macro(Other, NotLiveGCThing, typeInferenceArrayTypeTables) \ + macro(Other, NotLiveGCThing, typeInferenceObjectTypeTables) \ + macro(Other, NotLiveGCThing, compartmentObject) \ + macro(Other, NotLiveGCThing, crossCompartmentWrappersTable) \ + macro(Other, NotLiveGCThing, regexpCompartment) \ + macro(Other, NotLiveGCThing, debuggeesSet) CompartmentStats() : FOR_EACH_SIZE(ZERO_SIZE) objectsExtra(), extra() {} CompartmentStats(const CompartmentStats &other) @@ -386,32 +427,38 @@ struct CompartmentStats size_t sizeOfLiveGCThings() const { size_t n = 0; FOR_EACH_SIZE(ADD_SIZE_TO_N_IF_LIVE_GC_THING) n += objectsExtra.sizeOfLiveGCThings(); // Do nothing with |extra|. return n; } + void addToTabSizes(TabSizes *sizes) const { + FOR_EACH_SIZE(ADD_TO_TAB_SIZES); + objectsExtra.addToTabSizes(sizes); + // Do nothing with |extra|. + } + FOR_EACH_SIZE(DECL_SIZE) ObjectsExtraSizes objectsExtra; void *extra; // This field can be used by embedders. #undef FOR_EACH_SIZE }; struct RuntimeStats { #define FOR_EACH_SIZE(macro) \ - macro(_, gcHeapChunkTotal) \ - macro(_, gcHeapDecommittedArenas) \ - macro(_, gcHeapUnusedChunks) \ - macro(_, gcHeapUnusedArenas) \ - macro(_, gcHeapChunkAdmin) \ - macro(_, gcHeapGCThings) \ + macro(_, _, gcHeapChunkTotal) \ + macro(_, _, gcHeapDecommittedArenas) \ + macro(_, _, gcHeapUnusedChunks) \ + macro(_, _, gcHeapUnusedArenas) \ + macro(_, _, gcHeapChunkAdmin) \ + macro(_, _, gcHeapGCThings) \ RuntimeStats(mozilla::MallocSizeOf mallocSizeOf) : FOR_EACH_SIZE(ZERO_SIZE) runtime(), cTotals(), zTotals(), compartmentStatsVector(), zoneStatsVector(), @@ -483,11 +530,22 @@ extern JS_PUBLIC_API(size_t) SystemCompartmentCount(JSRuntime *rt); extern JS_PUBLIC_API(size_t) UserCompartmentCount(JSRuntime *rt); extern JS_PUBLIC_API(size_t) PeakSizeOfTemporary(const JSRuntime *rt); +extern JS_PUBLIC_API(bool) +AddSizeOfTab(JSRuntime *rt, JSObject *obj, mozilla::MallocSizeOf mallocSizeOf, + ObjectPrivateVisitor *opv, TabSizes *sizes); + } // namespace JS +#undef DECL_SIZE +#undef ZERO_SIZE +#undef COPY_OTHER_SIZE +#undef ADD_OTHER_SIZE +#undef ADD_SIZE_TO_N_IF_LIVE_GC_THING +#undef ADD_TO_TAB_SIZES + #endif /* js_MemoryMetrics_h */
--- a/js/src/gc/Iteration.cpp +++ b/js/src/gc/Iteration.cpp @@ -21,43 +21,66 @@ void js::TraceRuntime(JSTracer *trc) { JS_ASSERT(!IS_GC_MARKING_TRACER(trc)); AutoPrepareForTracing prep(trc->runtime); MarkRuntime(trc); } +static void +IterateCompartmentsArenasCells(JSRuntime *rt, Zone *zone, void *data, + JSIterateCompartmentCallback compartmentCallback, + IterateArenaCallback arenaCallback, + IterateCellCallback cellCallback) +{ + for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) + (*compartmentCallback)(rt, data, comp); + + for (size_t thingKind = 0; thingKind != FINALIZE_LIMIT; thingKind++) { + JSGCTraceKind traceKind = MapAllocToTraceKind(AllocKind(thingKind)); + size_t thingSize = Arena::thingSize(AllocKind(thingKind)); + + for (ArenaIter aiter(zone, AllocKind(thingKind)); !aiter.done(); aiter.next()) { + ArenaHeader *aheader = aiter.get(); + (*arenaCallback)(rt, data, aheader->getArena(), traceKind, thingSize); + for (CellIterUnderGC iter(aheader); !iter.done(); iter.next()) + (*cellCallback)(rt, data, iter.getCell(), traceKind, thingSize); + } + } +} + void js::IterateZonesCompartmentsArenasCells(JSRuntime *rt, void *data, IterateZoneCallback zoneCallback, JSIterateCompartmentCallback compartmentCallback, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback) { AutoPrepareForTracing prop(rt); for (ZonesIter zone(rt); !zone.done(); zone.next()) { (*zoneCallback)(rt, data, zone); - - for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) - (*compartmentCallback)(rt, data, comp); - - for (size_t thingKind = 0; thingKind != FINALIZE_LIMIT; thingKind++) { - JSGCTraceKind traceKind = MapAllocToTraceKind(AllocKind(thingKind)); - size_t thingSize = Arena::thingSize(AllocKind(thingKind)); + IterateCompartmentsArenasCells(rt, zone, data, + compartmentCallback, arenaCallback, cellCallback); + } +} - for (ArenaIter aiter(zone, AllocKind(thingKind)); !aiter.done(); aiter.next()) { - ArenaHeader *aheader = aiter.get(); - (*arenaCallback)(rt, data, aheader->getArena(), traceKind, thingSize); - for (CellIterUnderGC iter(aheader); !iter.done(); iter.next()) - (*cellCallback)(rt, data, iter.getCell(), traceKind, thingSize); - } - } - } +void +js::IterateZoneCompartmentsArenasCells(JSRuntime *rt, Zone *zone, void *data, + IterateZoneCallback zoneCallback, + JSIterateCompartmentCallback compartmentCallback, + IterateArenaCallback arenaCallback, + IterateCellCallback cellCallback) +{ + AutoPrepareForTracing prop(rt); + + (*zoneCallback)(rt, data, zone); + IterateCompartmentsArenasCells(rt, zone, data, + compartmentCallback, arenaCallback, cellCallback); } void js::IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback) { AutoPrepareForTracing prep(rt); for (js::GCChunkSet::Range r = rt->gcChunkSet.all(); !r.empty(); r.popFront())
--- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1269,28 +1269,39 @@ MarkStackRangeConservatively(JSTracer *t typedef void (*IterateChunkCallback)(JSRuntime *rt, void *data, gc::Chunk *chunk); typedef void (*IterateZoneCallback)(JSRuntime *rt, void *data, JS::Zone *zone); typedef void (*IterateArenaCallback)(JSRuntime *rt, void *data, gc::Arena *arena, JSGCTraceKind traceKind, size_t thingSize); typedef void (*IterateCellCallback)(JSRuntime *rt, void *data, void *thing, JSGCTraceKind traceKind, size_t thingSize); /* - * This function calls |compartmentCallback| on every compartment, - * |arenaCallback| on every in-use arena, and |cellCallback| on every in-use - * cell in the GC heap. + * This function calls |zoneCallback| on every zone, |compartmentCallback| on + * every compartment, |arenaCallback| on every in-use arena, and |cellCallback| + * on every in-use cell in the GC heap. */ extern void IterateZonesCompartmentsArenasCells(JSRuntime *rt, void *data, IterateZoneCallback zoneCallback, JSIterateCompartmentCallback compartmentCallback, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback); /* + * This function is like IterateZonesCompartmentsArenasCells, but does it for a + * single zone. + */ +extern void +IterateZoneCompartmentsArenasCells(JSRuntime *rt, Zone *zone, void *data, + IterateZoneCallback zoneCallback, + JSIterateCompartmentCallback compartmentCallback, + IterateArenaCallback arenaCallback, + IterateCellCallback cellCallback); + +/* * Invoke chunkCallback on every in-use chunk. */ extern void IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback); typedef void (*IterateScriptCallback)(JSRuntime *rt, void *data, JSScript *script); /*
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -38,16 +38,17 @@ #include "frontend/BytecodeCompiler.h" #include "gc/Marking.h" #include "jit/AsmJSModule.h" #include "jit/BaselineJIT.h" #include "js/MemoryMetrics.h" #include "js/OldDebugAPI.h" #include "vm/ArgumentsObject.h" #include "vm/Interpreter.h" +#include "vm/ProxyObject.h" #include "vm/RegExpStaticsObject.h" #include "vm/Shape.h" #include "jsatominlines.h" #include "jsboolinlines.h" #include "jscntxtinlines.h" #include "jscompartmentinlines.h" @@ -5675,18 +5676,34 @@ JSObject::addSizeOfExcludingThis(mozilla sizes->mallocHeapElementsAsmJS += mallocSizeOf(elements); #endif } else { sizes->mallocHeapElementsNonAsmJS += mallocSizeOf(elements); } } // Other things may be measured in the future if DMD indicates it is worthwhile. - // Note that sizes->private_ is measured elsewhere. - if (is<ArgumentsObject>()) { + if (is<JSFunction>() || + is<JSObject>() || + is<ArrayObject>() || + is<CallObject>() || + is<RegExpObject>() || + is<ProxyObject>()) + { + // Do nothing. But this function is hot, and we win by getting the + // common cases out of the way early. Some stats on the most common + // classes, as measured during a vanilla browser session: + // - (53.7%, 53.7%): Function + // - (18.0%, 71.7%): Object + // - (16.9%, 88.6%): Array + // - ( 3.9%, 92.5%): Call + // - ( 2.8%, 95.3%): RegExp + // - ( 1.0%, 96.4%): Proxy + + } else if (is<ArgumentsObject>()) { sizes->mallocHeapArgumentsData += as<ArgumentsObject>().sizeOfMisc(mallocSizeOf); } else if (is<RegExpStaticsObject>()) { sizes->mallocHeapRegExpStatics += as<RegExpStaticsObject>().sizeOfData(mallocSizeOf); } else if (is<PropertyIteratorObject>()) { sizes->mallocHeapPropertyIteratorData += as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf); #ifdef JS_ION } else if (is<AsmJSModuleObject>()) { as<AsmJSModuleObject>().addSizeOfMisc(mallocSizeOf, &sizes->nonHeapCodeAsmJS,
--- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -373,17 +373,17 @@ class JSObject : public js::ObjectImpl * The number of allocated slots is not stored explicitly, and changes to * the slots must track changes in the slot span. */ static bool growSlots(js::ThreadSafeContext *cx, js::HandleObject obj, uint32_t oldCount, uint32_t newCount); static void shrinkSlots(js::ThreadSafeContext *cx, js::HandleObject obj, uint32_t oldCount, uint32_t newCount); - bool hasDynamicSlots() const { return slots != nullptr; } + bool hasDynamicSlots() const { return !!slots; } protected: static inline bool updateSlotsForSpan(js::ThreadSafeContext *cx, js::HandleObject obj, size_t oldSpan, size_t newSpan); public: /* * Trigger the write barrier on a range of slots that will no longer be
--- a/js/src/vm/MemoryMetrics.cpp +++ b/js/src/vm/MemoryMetrics.cpp @@ -18,18 +18,19 @@ #include "jit/Ion.h" #include "vm/ArrayObject.h" #include "vm/Runtime.h" #include "vm/Shape.h" #include "vm/String.h" #include "vm/WrapperObject.h" using mozilla::DebugOnly; +using mozilla::MallocSizeOf; +using mozilla::MoveRef; using mozilla::OldMove; -using mozilla::MoveRef; using mozilla::PodEqual; using namespace js; using JS::RuntimeStats; using JS::ObjectPrivateVisitor; using JS::ZoneStats; using JS::CompartmentStats; @@ -263,23 +264,20 @@ StatsCellCallback(JSRuntime *rt, void *d cStats->objectsGCHeapDenseArray += thingSize; else if (obj->is<CrossCompartmentWrapperObject>()) cStats->objectsGCHeapCrossCompartmentWrapper += thingSize; else cStats->objectsGCHeapOrdinary += thingSize; obj->addSizeOfExcludingThis(rtStats->mallocSizeOf_, &cStats->objectsExtra); - // JSObject::sizeOfExcludingThis() doesn't measure objectsPrivate, - // so we do it here. if (ObjectPrivateVisitor *opv = closure->opv) { nsISupports *iface; - if (opv->getISupports_(obj, &iface) && iface) { + if (opv->getISupports_(obj, &iface) && iface) cStats->objectsPrivate += opv->sizeOfIncludingThis(iface); - } } break; } case JSTRACE_STRING: { JSString *str = static_cast<JSString *>(thing); size_t strCharsSize = str->sizeOfExcludingThis(rtStats->mallocSizeOf_); @@ -333,17 +331,16 @@ StatsCellCallback(JSRuntime *rt, void *d cStats->shapesGCHeapBase += thingSize; break; } case JSTRACE_SCRIPT: { JSScript *script = static_cast<JSScript *>(thing); CompartmentStats *cStats = GetCompartmentStats(script->compartment()); cStats->scriptsGCHeap += thingSize; - cStats->scriptsMallocHeapData += script->sizeOfData(rtStats->mallocSizeOf_); cStats->typeInferenceTypeScripts += script->sizeOfTypeScript(rtStats->mallocSizeOf_); #ifdef JS_ION jit::AddSizeOfBaselineData(script, rtStats->mallocSizeOf_, &cStats->baselineData, &cStats->baselineStubsFallback); cStats->ionData += jit::SizeOfIonData(script, rtStats->mallocSizeOf_); #endif @@ -441,24 +438,22 @@ JS::CollectRuntimeStats(JSRuntime *rt, R IterateChunks(rt, &rtStats->gcHeapDecommittedArenas, DecommittedArenasChunkCallback); // Take the per-compartment measurements. StatsClosure closure(rtStats, opv); if (!closure.init()) return false; - rtStats->runtime.scriptSources = 0; IterateZonesCompartmentsArenasCells(rt, &closure, StatsZoneCallback, StatsCompartmentCallback, StatsArenaCallback, StatsCellCallback); // Take the "explicit/js/runtime/" measurements. rt->addSizeOfIncludingThis(rtStats->mallocSizeOf_, &rtStats->runtime); - rtStats->gcHeapGCThings = 0; for (size_t i = 0; i < rtStats->zoneStatsVector.length(); i++) { ZoneStats &zStats = rtStats->zoneStatsVector[i]; rtStats->zTotals.add(zStats); // Move any strings which take up more than the sundries threshold // (counting all of their copies together) into notableStrings. FindNotableStrings(zStats); @@ -526,8 +521,67 @@ JS::UserCompartmentCount(JSRuntime *rt) } JS_PUBLIC_API(size_t) JS::PeakSizeOfTemporary(const JSRuntime *rt) { return rt->tempLifoAlloc.peakSizeOfExcludingThis(); } +namespace JS { + +JS_PUBLIC_API(bool) +AddSizeOfTab(JSRuntime *rt, JSObject *obj, MallocSizeOf mallocSizeOf, ObjectPrivateVisitor *opv, + TabSizes *sizes) +{ + class SimpleJSRuntimeStats : public JS::RuntimeStats + { + public: + SimpleJSRuntimeStats(MallocSizeOf mallocSizeOf) + : JS::RuntimeStats(mallocSizeOf) + {} + + virtual void initExtraZoneStats(JS::Zone *zone, JS::ZoneStats *zStats) + MOZ_OVERRIDE + {} + + virtual void initExtraCompartmentStats( + JSCompartment *c, JS::CompartmentStats *cStats) MOZ_OVERRIDE + {} + }; + + SimpleJSRuntimeStats rtStats(mallocSizeOf); + + JS::Zone *zone = GetObjectZone(obj); + + if (!rtStats.compartmentStatsVector.reserve(zone->compartments.length())) + return false; + + if (!rtStats.zoneStatsVector.reserve(1)) + return false; + + // Take the per-compartment measurements. + StatsClosure closure(&rtStats, opv); + if (!closure.init()) + return false; + IterateZoneCompartmentsArenasCells(rt, zone, &closure, StatsZoneCallback, + StatsCompartmentCallback, StatsArenaCallback, + StatsCellCallback); + + JS_ASSERT(rtStats.zoneStatsVector.length() == 1); + rtStats.zTotals.add(rtStats.zoneStatsVector[0]); + + for (size_t i = 0; i < rtStats.compartmentStatsVector.length(); i++) { + CompartmentStats &cStats = rtStats.compartmentStatsVector[i]; + rtStats.cTotals.add(cStats); + } + + for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) + comp->compartmentStats = NULL; + + rtStats.zTotals.addToTabSizes(sizes); + rtStats.cTotals.addToTabSizes(sizes); + + return true; +} + +} // namespace JS +
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -2411,17 +2411,17 @@ SizeOfTreeIncludingThis(nsINode *tree) class OrphanReporter : public JS::ObjectPrivateVisitor { public: OrphanReporter(GetISupportsFun aGetISupports) : JS::ObjectPrivateVisitor(aGetISupports) { } - virtual size_t sizeOfIncludingThis(nsISupports *aSupports) { + virtual size_t sizeOfIncludingThis(nsISupports *aSupports) MOZ_OVERRIDE { size_t n = 0; nsCOMPtr<nsINode> node = do_QueryInterface(aSupports); // https://bugzilla.mozilla.org/show_bug.cgi?id=773533#c11 explains // that we have to skip XBL elements because they violate certain // assumptions. Yuk. if (node && !node->IsInDoc() && !(node->IsElement() && node->AsElement()->IsInNamespace(kNameSpaceID_XBL))) { @@ -2669,16 +2669,35 @@ JSReporter::CollectReports(WindowPaths * REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect"), KIND_HEAP, xpconnect, "Memory used by XPConnect."); return NS_OK; } +static nsresult +JSSizeOfTab(JSObject *obj, size_t *jsObjectsSize, size_t *jsStringsSize, + size_t *jsPrivateSize, size_t *jsOtherSize) +{ + JSRuntime *rt = nsXPConnect::GetRuntimeInstance()->Runtime(); + + TabSizes sizes; + OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject); + NS_ENSURE_TRUE(JS::AddSizeOfTab(rt, obj, moz_malloc_size_of, + &orphanReporter, &sizes), + NS_ERROR_OUT_OF_MEMORY); + + *jsObjectsSize = sizes.objects; + *jsStringsSize = sizes.strings; + *jsPrivateSize = sizes.private_; + *jsOtherSize = sizes.other; + return NS_OK; +} + } // namespace xpc #ifdef MOZ_CRASHREPORTER static bool DiagnosticMemoryCallback(void *ptr, size_t size) { return CrashReporter::RegisterAppMemory(ptr, size) == NS_OK; } @@ -3035,16 +3054,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* // Register memory reporters and distinguished amount functions. NS_RegisterMemoryReporter(new JSMainRuntimeCompartmentsReporter); NS_RegisterMemoryReporter(new JSMainRuntimeTemporaryPeakReporter()); RegisterJSMainRuntimeGCHeapDistinguishedAmount(JSMainRuntimeGCHeapDistinguishedAmount); RegisterJSMainRuntimeTemporaryPeakDistinguishedAmount(JSMainRuntimeTemporaryPeakDistinguishedAmount); RegisterJSMainRuntimeCompartmentsSystemDistinguishedAmount(JSMainRuntimeCompartmentsSystemDistinguishedAmount); RegisterJSMainRuntimeCompartmentsUserDistinguishedAmount(JSMainRuntimeCompartmentsUserDistinguishedAmount); + mozilla::RegisterJSSizeOfTab(JSSizeOfTab); // Install a JavaScript 'debugger' keyword handler in debug builds only #ifdef DEBUG if (!JS_GetGlobalDebugHooks(runtime)->debuggerHandler) xpc_InstallJSDebuggerKeywordHandler(runtime); #endif }
--- a/layout/base/nsArenaMemoryStats.h +++ b/layout/base/nsArenaMemoryStats.h @@ -1,20 +1,81 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsArenaMemoryStats_h #define nsArenaMemoryStats_h +#include "mozilla/Assertions.h" +#include "mozilla/PodOperations.h" + +class nsTabSizes { +public: + enum Kind { + DOM, // DOM stuff. + Style, // Style stuff. + Other // Everything else. + }; + + nsTabSizes() { mozilla::PodZero(this); } + + void add(Kind kind, size_t n) + { + switch (kind) { + case DOM: mDom += n; break; + case Style: mStyle += n; break; + case Other: mOther += n; break; + default: MOZ_CRASH("bad nsTabSizes kind"); + } + } + + size_t mDom; + size_t mStyle; + size_t mOther; +}; + #define FRAME_ID_STAT_FIELD(classname) mArena##classname struct nsArenaMemoryStats { -#define FRAME_ID(classname) size_t FRAME_ID_STAT_FIELD(classname); -#include "nsFrameIdList.h" -#undef FRAME_ID - size_t mLineBoxes; - size_t mRuleNodes; - size_t mStyleContexts; - size_t mOther; +#define FOR_EACH_SIZE(macro) \ + macro(Other, mLineBoxes) \ + macro(Style, mRuleNodes) \ + macro(Style, mStyleContexts) \ + macro(Other, mOther) + + nsArenaMemoryStats() + : + #define ZERO_SIZE(kind, mSize) mSize(0), + FOR_EACH_SIZE(ZERO_SIZE) + #undef ZERO_SIZE + #define FRAME_ID(classname) FRAME_ID_STAT_FIELD(classname)(), + #include "nsFrameIdList.h" + #undef FRAME_ID + dummy() + {} + + void addToTabSizes(nsTabSizes *sizes) const + { + #define ADD_TO_TAB_SIZES(kind, mSize) sizes->add(nsTabSizes::kind, mSize); + FOR_EACH_SIZE(ADD_TO_TAB_SIZES) + #undef ADD_TO_TAB_SIZES + #define FRAME_ID(classname) \ + sizes->add(nsTabSizes::Other, FRAME_ID_STAT_FIELD(classname)); + #include "nsFrameIdList.h" + #undef FRAME_ID + } + + #define DECL_SIZE(kind, mSize) size_t mSize; + FOR_EACH_SIZE(DECL_SIZE) + #undef DECL_SIZE + #define FRAME_ID(classname) size_t FRAME_ID_STAT_FIELD(classname); + #include "nsFrameIdList.h" + #undef FRAME_ID + int dummy; // present just to absorb the trailing comma from FRAME_ID in the + // constructor + +#undef FOR_EACH_SIZE }; #endif // nsArenaMemoryStats_h
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6086,18 +6086,17 @@ PresShell::HandleEvent(nsIFrame* aFrame, } } if (aEvent->eventStructType == NS_KEY_EVENT && mDocument && mDocument->EventHandlingSuppressed()) { if (aEvent->message == NS_KEY_DOWN) { mNoDelayedKeyEvents = true; } else if (!mNoDelayedKeyEvents) { - nsDelayedEvent* event = - new nsDelayedKeyEvent(aEvent->AsKeyboardEvent()); + DelayedEvent* event = new DelayedKeyEvent(aEvent->AsKeyboardEvent()); if (!mDelayedEvents.AppendElement(event)) { delete event; } } return NS_OK; } nsIFrame* frame = aFrame; @@ -6308,17 +6307,17 @@ PresShell::HandleEvent(nsIFrame* aFrame, // Suppress mouse event if it's being targeted at an element inside // a document which needs events suppressed if (aEvent->eventStructType == NS_MOUSE_EVENT && frame->PresContext()->Document()->EventHandlingSuppressed()) { if (aEvent->message == NS_MOUSE_BUTTON_DOWN) { mNoDelayedMouseEvents = true; } else if (!mNoDelayedMouseEvents && aEvent->message == NS_MOUSE_BUTTON_UP) { - nsDelayedEvent* event = new nsDelayedMouseEvent(aEvent->AsMouseEvent()); + DelayedEvent* event = new DelayedMouseEvent(aEvent->AsMouseEvent()); if (!mDelayedEvents.AppendElement(event)) { delete event; } } return NS_OK; } @@ -6841,18 +6840,18 @@ PresShell::HandleEventInternal(WidgetEve return NS_OK; } if (mouseEvent->IsShift()) { aEvent->mFlags.mOnlyChromeDispatch = true; aEvent->mFlags.mRetargetToNonNativeAnonymous = true; } } - nsAutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput, - aEvent, mDocument); + AutoHandlingUserInputStatePusher userInpStatePusher(isHandlingUserInput, + aEvent, mDocument); if (aEvent->mFlags.mIsTrusted && aEvent->message == NS_MOUSE_MOVE) { nsIPresShell::AllowMouseCapture( nsEventStateManager::GetActiveEventStateManager() == manager); } nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent)); @@ -7601,19 +7600,19 @@ PresShell::FireOrClearDelayedEvents(bool mDelayedEvents.Clear(); return; } if (mDocument) { nsCOMPtr<nsIDocument> doc = mDocument; while (!mIsDestroying && mDelayedEvents.Length() && !doc->EventHandlingSuppressed()) { - nsAutoPtr<nsDelayedEvent> ev(mDelayedEvents[0].forget()); + nsAutoPtr<DelayedEvent> ev(mDelayedEvents[0].forget()); mDelayedEvents.RemoveElementAt(0); - ev->Dispatch(this); + ev->Dispatch(); } if (!doc->EventHandlingSuppressed()) { mDelayedEvents.Clear(); } } } static void @@ -8314,16 +8313,66 @@ nsIPresShell::RemovePostRefreshObserver( presContext->RefreshDriver()->RemovePostRefreshObserver(aObserver); return true; } //------------------------------------------------------ // End of protected and private methods on the PresShell //------------------------------------------------------ +//------------------------------------------------------------------ +//-- Delayed event Classes Impls +//------------------------------------------------------------------ + +PresShell::DelayedInputEvent::DelayedInputEvent() : + DelayedEvent(), + mEvent(nullptr) +{ +} + +PresShell::DelayedInputEvent::~DelayedInputEvent() +{ + delete mEvent; +} + +void +PresShell::DelayedInputEvent::Dispatch() +{ + if (!mEvent || !mEvent->widget) { + return; + } + nsCOMPtr<nsIWidget> widget = mEvent->widget; + nsEventStatus status; + widget->DispatchEvent(mEvent, status); +} + +PresShell::DelayedMouseEvent::DelayedMouseEvent(WidgetMouseEvent* aEvent) : + DelayedInputEvent() +{ + WidgetMouseEvent* mouseEvent = + new WidgetMouseEvent(aEvent->mFlags.mIsTrusted, + aEvent->message, + aEvent->widget, + aEvent->reason, + aEvent->context); + mouseEvent->AssignMouseEventData(*aEvent, false); + mEvent = mouseEvent; +} + +PresShell::DelayedKeyEvent::DelayedKeyEvent(WidgetKeyboardEvent* aEvent) : + DelayedInputEvent() +{ + WidgetKeyboardEvent* keyEvent = + new WidgetKeyboardEvent(aEvent->mFlags.mIsTrusted, + aEvent->message, + aEvent->widget); + keyEvent->AssignKeyEventData(*aEvent, false); + mEvent = keyEvent; +} + // Start of DEBUG only code #ifdef DEBUG static void LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg) { nsAutoString n1, n2;
--- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -29,19 +29,18 @@ #include "nsCRT.h" #include "nsAutoPtr.h" #include "nsIWidget.h" #include "nsStyleSet.h" #include "nsFrameSelection.h" #include "nsContentUtils.h" // For AddScriptBlocker(). #include "nsRefreshDriver.h" #include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/MouseEvents.h" -#include "mozilla/TextEvents.h" class nsRange; class nsIDragService; class nsCSSStyleSheet; struct RangePaintInfo; struct nsCallbackEventRequest; #ifdef MOZ_REFLOW_PERF @@ -542,77 +541,45 @@ protected: nsresult rv = NS_OK; if (GetCurrentEventFrame()) { rv = HandleEventInternal(aEvent, aStatus); } PopCurrentEventInfo(); return rv; } - class nsDelayedEvent - { - public: - virtual ~nsDelayedEvent() {}; - virtual void Dispatch(PresShell* aShell) {} - }; - - class nsDelayedInputEvent : public nsDelayedEvent + class DelayedEvent { public: - virtual void Dispatch(PresShell* aShell) - { - if (mEvent && mEvent->widget) { - nsCOMPtr<nsIWidget> w = mEvent->widget; - nsEventStatus status; - w->DispatchEvent(mEvent, status); - } - } + virtual ~DelayedEvent() { } + virtual void Dispatch() { } + }; + + class DelayedInputEvent : public DelayedEvent + { + public: + virtual void Dispatch() MOZ_OVERRIDE; protected: - nsDelayedInputEvent() - : nsDelayedEvent(), mEvent(nullptr) {} - - virtual ~nsDelayedInputEvent() - { - delete mEvent; - } + DelayedInputEvent(); + virtual ~DelayedInputEvent(); mozilla::WidgetInputEvent* mEvent; }; - class nsDelayedMouseEvent : public nsDelayedInputEvent + class DelayedMouseEvent : public DelayedInputEvent { public: - nsDelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent) : - nsDelayedInputEvent() - { - mozilla::WidgetMouseEvent* mouseEvent = - new mozilla::WidgetMouseEvent(aEvent->mFlags.mIsTrusted, - aEvent->message, - aEvent->widget, - aEvent->reason, - aEvent->context); - mouseEvent->AssignMouseEventData(*aEvent, false); - mEvent = mouseEvent; - } + DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent); }; - class nsDelayedKeyEvent : public nsDelayedInputEvent + class DelayedKeyEvent : public DelayedInputEvent { public: - nsDelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent) : - nsDelayedInputEvent() - { - mozilla::WidgetKeyboardEvent* keyEvent = - new mozilla::WidgetKeyboardEvent(aEvent->mFlags.mIsTrusted, - aEvent->message, - aEvent->widget); - keyEvent->AssignKeyEventData(*aEvent, false); - mEvent = keyEvent; - } + DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent); }; // Check if aEvent is a mouse event and record the mouse location for later // synth mouse moves. void RecordMouseLocation(mozilla::WidgetGUIEvent* aEvent); class nsSynthMouseMoveEvent MOZ_FINAL : public nsARefreshObserver { public: nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll) @@ -754,17 +721,17 @@ protected: // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after // we finish reflowing mCurrentReflowRoot. nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty; // Reflow roots that need to be reflowed. nsTArray<nsIFrame*> mDirtyRoots; - nsTArray<nsAutoPtr<nsDelayedEvent> > mDelayedEvents; + nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents; nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent; nsCOMPtr<nsITimer> mAsyncResizeEventTimer; private: nsIFrame* mCurrentEventFrame; nsCOMPtr<nsIContent> mCurrentEventContent; nsTArray<nsIFrame*> mCurrentEventFrameStack; nsCOMArray<nsIContent> mCurrentEventContentStack; protected:
--- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -9,17 +9,17 @@ #include "nsIWeakReference.h" #include "nsISelection.h" #include "nsISelectionController.h" #include "nsISelectionPrivate.h" #include "nsRange.h" #include "nsThreadUtils.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" struct CachedOffsetForFrame; class nsAutoScrollTimer; class nsIContentIterator; class nsIFrame; class nsFrameSelection; struct SelectionDetails;
--- a/layout/generic/nsFrameSelection.h +++ b/layout/generic/nsFrameSelection.h @@ -3,17 +3,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsFrameSelection_h___ #define nsFrameSelection_h___ #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" #include "mozilla/Selection.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" #include "nsIFrame.h" #include "nsIContent.h" #include "nsISelectionController.h" #include "nsITableCellLayout.h" #include "nsIDOMElement.h" #include "nsRange.h" class nsTableOuterFrame;
--- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -140,17 +140,16 @@ extern "C" { extern void DisposeGWorld(GWorldPtr offscreenGWorld) __attribute__((weak_import)); #endif /* __QDOFFSCREEN__ */ } #endif /* #if defined(XP_MACOSX) && !defined(__LP64__) */ using namespace mozilla; -using namespace mozilla::plugins; using namespace mozilla::layers; class PluginBackgroundSink : public ReadbackSink { public: PluginBackgroundSink(nsObjectFrame* aFrame, uint64_t aStartSequenceNumber) : mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {} ~PluginBackgroundSink() { @@ -1786,17 +1785,17 @@ nsObjectFrame::PaintPlugin(nsDisplayList nsPoint origin; gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect); if (nativeDraw.IsDoublePass()) { // OOP plugin specific: let the shim know before we paint if we are doing a // double pass render. If this plugin isn't oop, the register window message // will be ignored. NPEvent pluginEvent; - pluginEvent.event = DoublePassRenderingEvent(); + pluginEvent.event = plugins::DoublePassRenderingEvent(); pluginEvent.wParam = 0; pluginEvent.lParam = 0; if (pluginEvent.event) inst->HandleEvent(&pluginEvent, nullptr); } do { HDC hdc = nativeDraw.BeginNativeDrawing(); if (!hdc)
--- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -2415,18 +2415,19 @@ private: nsStyleCoord mFilterParameter; // coord, percent, factor, angle union { nsIURI* mURL; nsCSSShadowArray* mDropShadow; }; }; template<> -struct nsTArray_CopyElements<nsStyleFilter> - : public nsTArray_CopyWithConstructors<nsStyleFilter> {}; +struct nsTArray_CopyChooser<nsStyleFilter> { + typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type; +}; struct nsStyleSVGReset { nsStyleSVGReset(); nsStyleSVGReset(const nsStyleSVGReset& aSource); ~nsStyleSVGReset(); void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW { return aContext->AllocateFromShell(sz);
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -14,16 +14,17 @@ #include "nsINameSpaceManager.h" #include "nsViewManager.h" #include "nsWidgetsCID.h" #include "nsMenuFrame.h" #include "nsMenuBarFrame.h" #include "nsPopupSetFrame.h" #include "nsEventDispatcher.h" #include "nsPIDOMWindow.h" +#include "nsIDOMKeyEvent.h" #include "nsIDOMScreen.h" #include "nsIPresShell.h" #include "nsFrameManager.h" #include "nsIDocument.h" #include "nsRect.h" #include "nsIComponentManager.h" #include "nsBoxLayoutState.h" #include "nsIScrollableFrame.h" @@ -1645,17 +1646,17 @@ nsMenuPopupFrame::FindMenuWithShortcut(n bool isMenu = parentContent && !parentContent->NodeInfo()->Equals(nsGkAtoms::menulist, kNameSpaceID_XUL); static DOMTimeStamp lastKeyTime = 0; DOMTimeStamp keyTime; aKeyEvent->GetTimeStamp(&keyTime); if (charCode == 0) { - if (keyCode == NS_VK_BACK) { + if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE) { if (!isMenu && !mIncrementalString.IsEmpty()) { mIncrementalString.SetLength(mIncrementalString.Length() - 1); return nullptr; } else { #ifdef XP_WIN nsCOMPtr<nsISound> soundInterface = do_CreateInstance("@mozilla.org/sound;1"); if (soundInterface)
--- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -1841,17 +1841,18 @@ nsXULPopupManager::HandleKeyboardNavigat if (item) itemFrame = item->Frame(); else if (mActiveMenuBar) itemFrame = mActiveMenuBar; else return false; nsNavigationDirection theDirection; - NS_ASSERTION(aKeyCode >= NS_VK_END && aKeyCode <= NS_VK_DOWN, "Illegal key code"); + NS_ASSERTION(aKeyCode >= nsIDOMKeyEvent::DOM_VK_END && + aKeyCode <= nsIDOMKeyEvent::DOM_VK_DOWN, "Illegal key code"); theDirection = NS_DIRECTION_FROM_KEY_CODE(itemFrame, aKeyCode); // if a popup is open, first check for navigation within the popup if (item && HandleKeyboardNavigationInPopup(item, theDirection)) return true; // no popup handled the key, so check the active menubar, if any if (mActiveMenuBar) { @@ -2349,18 +2350,18 @@ nsXULMenuCommandEvent::Run() nsPresContext* presContext = menuFrame->PresContext(); nsCOMPtr<nsIPresShell> shell = presContext->PresShell(); nsRefPtr<nsViewManager> kungFuDeathGrip = shell->GetViewManager(); // Deselect ourselves. if (mCloseMenuMode != CloseMenuMode_None) menuFrame->SelectMenu(false); - nsAutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, - shell->GetDocument()); + AutoHandlingUserInputStatePusher userInpStatePusher(mUserInput, nullptr, + shell->GetDocument()); nsContentUtils::DispatchXULCommand(mMenu, mIsTrusted, nullptr, shell, mControl, mAlt, mShift, mMeta); } if (popup && mCloseMenuMode != CloseMenuMode_None) pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false); return NS_OK;
--- a/modules/libmar/tool/mar.c +++ b/modules/libmar/tool/mar.c @@ -149,17 +149,17 @@ int main(int argc, char **argv) { argc -= 2; } #if defined(XP_WIN) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY) /* -D DERFilePath, also matches -D[index] DERFilePath We allow an index for verifying to be symmetric with the import and export command line arguments. */ else if (argv[1][0] == '-' && argv[1][1] == 'D' && - (argv[1][2] == '0' + certCount || argv[1][2] == '\0')) { + (argv[1][2] == (char)('0' + certCount) || argv[1][2] == '\0')) { if (certCount >= MAX_SIGNATURES) { print_usage(); return -1; } DERFilePaths[certCount++] = argv[2]; argv += 2; argc -= 2; }
--- a/testing/mochitest/runtestsremote.py +++ b/testing/mochitest/runtestsremote.py @@ -610,20 +610,19 @@ def main(): log.info("Running tests %d-%d/%d", start+1, end, len(tests)) deviceRoot = dm.getDeviceRoot() dm.removeFile(os.path.join(deviceRoot, "fennec_ids.txt")) fennec_ids = os.path.abspath("fennec_ids.txt") if not os.path.exists(fennec_ids) and options.robocopIds: fennec_ids = options.robocopIds dm.pushFile(fennec_ids, os.path.join(deviceRoot, "fennec_ids.txt")) - options.extraPrefs.append('robocop.logfile="%s/robocop.log"' % deviceRoot) options.extraPrefs.append('browser.search.suggest.enabled=true') options.extraPrefs.append('browser.search.suggest.prompted=true') - options.extraPrefs.append('layout.css.devPixelsPerPx="1.0"') + options.extraPrefs.append('layout.css.devPixelsPerPx=1.0') options.extraPrefs.append('browser.chrome.dynamictoolbar=false') if (options.dm_trans == 'adb' and options.robocopApk): dm._checkCmd(["install", "-r", options.robocopApk]) retVal = None for test in robocop_tests: if options.testPath and options.testPath != test['name']:
--- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul +++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul @@ -150,16 +150,31 @@ // and this file hasn't been updated appropriately. dummy = mgr[amounts[i]]; ok(dummy !== undefined, "accessed an unknown distinguished amount: " + amounts[i]); } catch (ex) { } } + // Run sizeOfTab() to make sure it doesn't crash. We can't check the result + // values because they're non-deterministic. + let jsObjectsSize = {}; + let jsStringsSize = {}; + let jsOtherSize = {}; + let domSize = {}; + let styleSize = {}; + let otherSize = {}; + let totalSize = {}; + let jsMilliseconds = {}; + let nonJSMilliseconds = {}; + mgr.sizeOfTab(window, jsObjectsSize, jsStringsSize, jsOtherSize, + domSize, styleSize, otherSize, totalSize, + jsMilliseconds, nonJSMilliseconds); + let e = mgr.enumerateReporters(); while (e.hasMoreElements()) { let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter); r.collectReports(handleReport, null); // Access |name| to make sure it doesn't crash or assert. dummy = r.name; }
--- a/toolkit/content/widgets/videocontrols.xml +++ b/toolkit/content/widgets/videocontrols.xml @@ -235,25 +235,19 @@ <tr> <td class="statLabel">&stats.volume;</td> <td class="statValue"><span class="statVolume"/></td> </tr> <tr> <!-- Localization note: readyState is a HTML5 API MediaElement-specific attribute and should not be localized. --> <td class="statLabel">readyState</td> <td class="statValue"><span class="statReadyState"/></td> </tr> <tr> - <td class="statLabel">&stats.channels;</td> <td class="statValue"><span class="statChannels"/></td> - </tr> - <tr> <!-- Localization note: networkState is a HTML5 API MediaElement-specific attribute and should not be localized. --> <td class="statLabel">networkState</td> <td class="statValue"><span class="statNetState"/></td> </tr> - <tr> - <td class="statLabel">&stats.sampleRate;</td> <td class="statValue"><span class="statSampleRate"/></td> - </tr> <tr style="height: 1em;"/> <tr> <td class="statLabel">&stats.framesParsed;</td> <td class="statValue"><span class="statFramesParsed"/></td> </tr> <tr> <td class="statLabel">&stats.framesDecoded;</td> @@ -1213,19 +1207,16 @@ s.framesDecoded.textContent = v.mozDecodedFrames; s.framesPresented.textContent = v.mozPresentedFrames; s.framesPainted.textContent = v.mozPaintedFrames; let volume = Math.round(v.volume * 100) + "%"; if (v.muted) volume += " (muted)"; s.volume.textContent = volume; - - s.channels.textContent = v.mozChannels; - s.sampRate.textContent = (v.mozSampleRate / 1000).toFixed(3) + " kHz"; }, keyHandler : function(event) { // Ignore keys when content might be providing its own. if (!this.video.hasAttribute("controls")) return; var keystroke = ""; @@ -1405,18 +1396,16 @@ this.clickToPlay = document.getAnonymousElementByAttribute(binding, "class", "clickToPlay"); this.fullscreenButton = document.getAnonymousElementByAttribute(binding, "class", "fullscreenButton"); this.statsTable = document.getAnonymousElementByAttribute(binding, "class", "statsTable"); this.stats.filename = document.getAnonymousElementByAttribute(binding, "class", "statFilename"); this.stats.size = document.getAnonymousElementByAttribute(binding, "class", "statSize"); this.stats.activity = document.getAnonymousElementByAttribute(binding, "class", "statActivity"); this.stats.volume = document.getAnonymousElementByAttribute(binding, "class", "statVolume"); - this.stats.channels = document.getAnonymousElementByAttribute(binding, "class", "statChannels"); - this.stats.sampRate = document.getAnonymousElementByAttribute(binding, "class", "statSampleRate"); this.stats.readyState = document.getAnonymousElementByAttribute(binding, "class", "statReadyState"); this.stats.netState = document.getAnonymousElementByAttribute(binding, "class", "statNetState"); this.stats.framesParsed = document.getAnonymousElementByAttribute(binding, "class", "statFramesParsed"); this.stats.framesDecoded = document.getAnonymousElementByAttribute(binding, "class", "statFramesDecoded"); this.stats.framesPresented = document.getAnonymousElementByAttribute(binding, "class", "statFramesPresented"); this.stats.framesPainted = document.getAnonymousElementByAttribute(binding, "class", "statFramesPainted"); this.setupInitialState();
--- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -84,17 +84,17 @@ STATIC_LIBS += \ ifdef MOZ_CONTENT_SANDBOX #{ STATIC_LIBS += sandbox_s endif #} ifdef MOZ_B2G_RIL #{ STATIC_LIBS += mozril_s endif #} -ifdef MOZ_B2G_BT #{ +ifdef MOZ_B2G_BT_BLUEZ #{ STATIC_LIBS += mozdbus_s ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) OS_LIBS += -ldbus endif endif #} ifneq ($(strip $(MOZ_B2G_RIL)$(MOZ_B2G_BT)),) #{ STATIC_LIBS += mozipcunixsocket_s mozkeystore_s
--- a/toolkit/locales/en-US/chrome/global/videocontrols.dtd +++ b/toolkit/locales/en-US/chrome/global/videocontrols.dtd @@ -12,18 +12,16 @@ <!ENTITY stats.media "Media"> <!ENTITY stats.size "Size"> <!ENTITY stats.activity "Activity"> <!ENTITY stats.activityPaused "Paused"> <!ENTITY stats.activityPlaying "Playing"> <!ENTITY stats.activityEnded "Ended"> <!ENTITY stats.activitySeeking "(seeking)"> <!ENTITY stats.volume "Volume"> -<!ENTITY stats.channels "Channels"> -<!ENTITY stats.sampleRate "Sample Rate"> <!ENTITY stats.framesParsed "Frames parsed"> <!ENTITY stats.framesDecoded "Frames decoded"> <!ENTITY stats.framesPresented "Frames presented"> <!ENTITY stats.framesPainted "Frames painted"> <!ENTITY error.aborted "Video loading stopped."> <!ENTITY error.network "Video playback aborted due to a network error."> <!ENTITY error.decode "Video can't be played because the file is corrupt.">
--- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -615,22 +615,24 @@ SyncProfile* NewSyncProfile() SyncProfile* TableTicker::GetBacktrace() { SyncProfile* profile = NewSyncProfile(); TickSample sample; sample.threadProfile = profile; +#if defined(HAVE_NATIVE_UNWIND) #if defined(XP_WIN) || defined(LINUX) tickcontext_t context; sample.PopulateContext(&context); #elif defined(XP_MACOSX) sample.PopulateContext(nullptr); #endif +#endif sample.isSamplingCurrentThread = true; sample.timestamp = mozilla::TimeStamp::Now(); if (!HasUnwinderThread()) { profile->BeginUnwind(); }
--- a/view/public/nsView.h +++ b/view/public/nsView.h @@ -6,16 +6,17 @@ #ifndef nsView_h__ #define nsView_h__ #include "nsCoord.h" #include "nsRect.h" #include "nsPoint.h" #include "nsRegion.h" #include "nsCRT.h" +#include "nsWidgetInitData.h" // for nsWindowType #include "nsIWidgetListener.h" #include "mozilla/EventForwards.h" class nsViewManager; class nsIWidget; class nsIFrame; // Enumerated type to indicate the visibility of a layer.
--- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -22,16 +22,17 @@ #include "mozilla/StartupTimeline.h" #include "GeckoProfiler.h" #include "nsRefreshDriver.h" #include "mozilla/Preferences.h" #include "nsContentUtils.h" // for nsAutoScriptBlocker #include "nsLayoutUtils.h" #include "Layers.h" #include "gfxPlatform.h" +#include "nsIDocument.h" /** XXX TODO XXX DeCOMify newly private methods Optimize view storage */
--- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -59,16 +59,18 @@ namespace mozilla { #undef NS_EVENT_CLASS #undef NS_ROOT_EVENT_CLASS // BasicEvents.h struct EventFlags; // TextEvents.h struct AlternativeCharCode; + +// TextRange.h struct TextRangeStyle; struct TextRange; typedef TextRange* TextRangeArray; } // namespace mozilla #endif // mozilla_EventForwards_h__
--- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -6,23 +6,22 @@ #ifndef mozilla_TextEvents_h__ #define mozilla_TextEvents_h__ #include <stdint.h> #include "mozilla/Assertions.h" #include "mozilla/BasicEvents.h" #include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily -#include "nsColor.h" +#include "mozilla/TextRange.h" #include "nsCOMPtr.h" #include "nsIDOMKeyEvent.h" #include "nsITransferable.h" #include "nsRect.h" #include "nsStringGlue.h" -#include "nsStyleConsts.h" #include "nsTArray.h" /****************************************************************************** * virtual keycode values ******************************************************************************/ #define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode @@ -145,158 +144,16 @@ public: // Don't copy mNativeKeyEvent because it may be referred after its instance // is destroyed. mNativeKeyEvent = nullptr; mUniqueId = aEvent.mUniqueId; } }; /****************************************************************************** - * mozilla::TextRangeStyle - ******************************************************************************/ - -struct TextRangeStyle -{ - enum { - LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, - LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, - LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, - LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, - LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, - LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY - }; - - enum { - DEFINED_NONE = 0x00, - DEFINED_LINESTYLE = 0x01, - DEFINED_FOREGROUND_COLOR = 0x02, - DEFINED_BACKGROUND_COLOR = 0x04, - DEFINED_UNDERLINE_COLOR = 0x08 - }; - - // Initialize all members, because TextRange instances may be compared by - // memcomp. - TextRangeStyle() - { - Clear(); - } - - void Clear() - { - mDefinedStyles = DEFINED_NONE; - mLineStyle = LINESTYLE_NONE; - mIsBoldLine = false; - mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); - } - - bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } - - bool IsLineStyleDefined() const - { - return (mDefinedStyles & DEFINED_LINESTYLE) != 0; - } - - bool IsForegroundColorDefined() const - { - return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; - } - - bool IsBackgroundColorDefined() const - { - return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; - } - - bool IsUnderlineColorDefined() const - { - return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; - } - - bool IsNoChangeStyle() const - { - return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && - IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; - } - - bool Equals(const TextRangeStyle& aOther) - { - if (mDefinedStyles != aOther.mDefinedStyles) - return false; - if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || - !mIsBoldLine != !aOther.mIsBoldLine)) - return false; - if (IsForegroundColorDefined() && - (mForegroundColor != aOther.mForegroundColor)) - return false; - if (IsBackgroundColorDefined() && - (mBackgroundColor != aOther.mBackgroundColor)) - return false; - if (IsUnderlineColorDefined() && - (mUnderlineColor != aOther.mUnderlineColor)) - return false; - return true; - } - - bool operator !=(const TextRangeStyle &aOther) - { - return !Equals(aOther); - } - - bool operator ==(const TextRangeStyle &aOther) - { - return Equals(aOther); - } - - uint8_t mDefinedStyles; - uint8_t mLineStyle; // DEFINED_LINESTYLE - - bool mIsBoldLine; // DEFINED_LINESTYLE - - nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR - nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR - nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR -}; - -/****************************************************************************** - * mozilla::TextRange - ******************************************************************************/ - -// Sync with nsIPrivateTextRange.h when you change these constants. -#define NS_TEXTRANGE_CARETPOSITION 0x01 -#define NS_TEXTRANGE_RAWINPUT 0x02 -#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 -#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 -#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 - -struct TextRange -{ - TextRange() : - mStartOffset(0), mEndOffset(0), mRangeType(0) - { - } - - uint32_t mStartOffset; - // XXX Storing end offset makes the initializing code very complicated. - // We should replace it with mLength. - uint32_t mEndOffset; - uint32_t mRangeType; - - TextRangeStyle mRangeStyle; - - uint32_t Length() const { return mEndOffset - mStartOffset; } -}; - -/****************************************************************************** - * mozilla::TextRangeArray - * - * XXX This should be replaced with nsTArray<TextRange>. - ******************************************************************************/ - -typedef TextRange* TextRangeArray; - -/****************************************************************************** * mozilla::WidgetTextEvent * * XXX WidgetTextEvent is fired with compositionupdate event almost every time. * This wastes performance and the cost of mantaining each platform's * implementation. Therefore, we should merge WidgetTextEvent and * WidgetCompositionEvent. Then, DOM compositionupdate should be fired * from TextComposition automatically. ******************************************************************************/
new file mode 100644 --- /dev/null +++ b/widget/TextRange.h @@ -0,0 +1,162 @@ +/* -*- 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 mozilla_TextRage_h_ +#define mozilla_TextRage_h_ + +#include <stdint.h> + +#include "nsColor.h" +#include "nsStyleConsts.h" + +namespace mozilla { + +/****************************************************************************** + * mozilla::TextRangeStyle + ******************************************************************************/ + +struct TextRangeStyle +{ + enum + { + LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, + LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, + LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, + LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, + LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, + LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY + }; + + enum + { + DEFINED_NONE = 0x00, + DEFINED_LINESTYLE = 0x01, + DEFINED_FOREGROUND_COLOR = 0x02, + DEFINED_BACKGROUND_COLOR = 0x04, + DEFINED_UNDERLINE_COLOR = 0x08 + }; + + // Initialize all members, because TextRange instances may be compared by + // memcomp. + TextRangeStyle() + { + Clear(); + } + + void Clear() + { + mDefinedStyles = DEFINED_NONE; + mLineStyle = LINESTYLE_NONE; + mIsBoldLine = false; + mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); + } + + bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } + + bool IsLineStyleDefined() const + { + return (mDefinedStyles & DEFINED_LINESTYLE) != 0; + } + + bool IsForegroundColorDefined() const + { + return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; + } + + bool IsBackgroundColorDefined() const + { + return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; + } + + bool IsUnderlineColorDefined() const + { + return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; + } + + bool IsNoChangeStyle() const + { + return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && + IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; + } + + bool Equals(const TextRangeStyle& aOther) + { + if (mDefinedStyles != aOther.mDefinedStyles) + return false; + if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || + !mIsBoldLine != !aOther.mIsBoldLine)) + return false; + if (IsForegroundColorDefined() && + (mForegroundColor != aOther.mForegroundColor)) + return false; + if (IsBackgroundColorDefined() && + (mBackgroundColor != aOther.mBackgroundColor)) + return false; + if (IsUnderlineColorDefined() && + (mUnderlineColor != aOther.mUnderlineColor)) + return false; + return true; + } + + bool operator !=(const TextRangeStyle &aOther) + { + return !Equals(aOther); + } + + bool operator ==(const TextRangeStyle &aOther) + { + return Equals(aOther); + } + + uint8_t mDefinedStyles; + uint8_t mLineStyle; // DEFINED_LINESTYLE + + bool mIsBoldLine; // DEFINED_LINESTYLE + + nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR + nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR + nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR +}; + +/****************************************************************************** + * mozilla::TextRange + ******************************************************************************/ + +// Sync with nsIPrivateTextRange.h when you change these constants. +#define NS_TEXTRANGE_CARETPOSITION 0x01 +#define NS_TEXTRANGE_RAWINPUT 0x02 +#define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 +#define NS_TEXTRANGE_CONVERTEDTEXT 0x04 +#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 + +struct TextRange +{ + TextRange() : + mStartOffset(0), mEndOffset(0), mRangeType(0) + { + } + + uint32_t mStartOffset; + // XXX Storing end offset makes the initializing code very complicated. + // We should replace it with mLength. + uint32_t mEndOffset; + uint32_t mRangeType; + + TextRangeStyle mRangeStyle; + + uint32_t Length() const { return mEndOffset - mStartOffset; } +}; + +/****************************************************************************** + * mozilla::TextRangeArray + * + * XXX This should be replaced with nsTArray<TextRange>. + ******************************************************************************/ + +typedef TextRange* TextRangeArray; + +} // namespace mozilla + +#endif // mozilla_TextRage_h_
--- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -6,18 +6,19 @@ #ifndef NSWINDOW_H_ #define NSWINDOW_H_ #include "nsBaseWidget.h" #include "gfxPoint.h" #include "nsIIdleServiceInternal.h" #include "nsTArray.h" #include "AndroidJavaWrappers.h" +#include "mozilla/EventForwards.h" #include "mozilla/StaticPtr.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" class gfxASurface; struct ANPEvent; namespace mozilla { class AndroidGeckoEvent;
--- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -17,16 +17,17 @@ #include "prlog.h" #include "nsTArray.h" #include "nsPrimitiveHelpers.h" #include "prtime.h" #include "prthread.h" #include <gtk/gtk.h> #include <gdk/gdkx.h> #include "nsCRT.h" +#include "mozilla/BasicEvents.h" #include "mozilla/Services.h" #include "gfxASurface.h" #include "gfxXlibSurface.h" #include "gfxContext.h" #include "nsImageToPixbuf.h" #include "nsPresContext.h" #include "nsIContent.h"
--- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -25,17 +25,17 @@ #ifdef MOZ_X11 #include <gdk/gdkx.h> #endif /* MOZ_X11 */ #ifdef ACCESSIBILITY #include "mozilla/a11y/Accessible.h" #endif -#include "mozilla/MouseEvents.h" +#include "mozilla/EventForwards.h" #include "nsGtkIMModule.h" #undef LOG #ifdef MOZ_LOGGING // make sure that logging is enabled before including prlog.h #define FORCE_PR_LOG
--- a/widget/moz.build +++ b/widget/moz.build @@ -113,16 +113,17 @@ EXPORTS.mozilla += [ 'BasicEvents.h', 'ContentEvents.h', 'EventClassList.h', 'EventForwards.h', 'LookAndFeel.h', 'MiscEvents.h', 'MouseEvents.h', 'TextEvents.h', + 'TextRange.h', 'TouchEvents.h', 'WidgetUtils.h', ] if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']: EXPORTS.mozilla += [ 'WidgetTraceEvent.h', ]
--- a/widget/nsIWidgetListener.h +++ b/widget/nsIWidgetListener.h @@ -1,22 +1,24 @@ /* 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 nsIWidgetListener_h__ #define nsIWidgetListener_h__ -#include "nscore.h" -#include "nsIXULWindow.h" -#include "nsRegion.h" -#include "mozilla/BasicEvents.h" +#include <stdint.h> + +#include "mozilla/EventForwards.h" class nsView; +class nsIntRegion; class nsIPresShell; +class nsIWidget; +class nsIXULWindow; /** * sizemode is an adjunct to widget size */ enum nsSizeMode { nsSizeMode_Normal = 0, nsSizeMode_Minimized, @@ -38,107 +40,106 @@ class nsIWidgetListener { public: /** * If this listener is for an nsIXULWindow, return it. If this is null, then * this is likely a listener for a view, which can be determined using * GetView. If both methods return null, this will be an nsWebBrowser. */ - virtual nsIXULWindow* GetXULWindow() { return nullptr; } + virtual nsIXULWindow* GetXULWindow(); /** * If this listener is for an nsView, return it. */ - virtual nsView* GetView() { return nullptr; } + virtual nsView* GetView(); /** * Return the presshell for this widget listener. */ - virtual nsIPresShell* GetPresShell() { return nullptr; } + virtual nsIPresShell* GetPresShell(); /** * Called when a window is moved to location (x, y). Returns true if the * notification was handled. Coordinates are outer window screen coordinates. */ - virtual bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY) { return false; } + virtual bool WindowMoved(nsIWidget* aWidget, int32_t aX, int32_t aY); /** * Called when a window is resized to (width, height). Returns true if the * notification was handled. Coordinates are outer window screen coordinates. */ - virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) { return false; } + virtual bool WindowResized(nsIWidget* aWidget, + int32_t aWidth, int32_t aHeight); /** * Called when the size mode (minimized, maximized, fullscreen) is changed. */ - virtual void SizeModeChanged(nsSizeMode sizeMode) { } + virtual void SizeModeChanged(nsSizeMode aSizeMode); /** * Called when the z-order of the window is changed. Returns true if the * notification was handled. aPlacement indicates the new z order. If * placement is nsWindowZRelative, then aRequestBelow should be the * window to place below. On return, aActualBelow will be set to the * window actually behind. This generally only applies to Windows. */ - virtual bool ZLevelChanged(bool aImmediate, nsWindowZ *aPlacement, - nsIWidget* aRequestBelow, nsIWidget** aActualBelow) { return false; } + virtual bool ZLevelChanged(bool aImmediate, nsWindowZ* aPlacement, + nsIWidget* aRequestBelow, + nsIWidget** aActualBelow); /** * Called when the window is activated and focused. */ - virtual void WindowActivated() { } + virtual void WindowActivated(); /** * Called when the window is deactivated and no longer focused. */ - virtual void WindowDeactivated() { } + virtual void WindowDeactivated(); /** * Called when the show/hide toolbar button on the Mac titlebar is pressed. */ - virtual void OSToolbarButtonPressed() { } + virtual void OSToolbarButtonPressed(); /** * Called when a request is made to close the window. Returns true if the * notification was handled. Returns true if the notification was handled. */ - virtual bool RequestWindowClose(nsIWidget* aWidget) { return false; } + virtual bool RequestWindowClose(nsIWidget* aWidget); /* * Indicate that a paint is about to occur on this window. This is called * at a time when it's OK to change the geometry of this widget or of * other widgets. Must be called before every call to PaintWindow. */ - virtual void WillPaintWindow(nsIWidget* aWidget) { } + virtual void WillPaintWindow(nsIWidget* aWidget); /** * Paint the specified region of the window. Returns true if the * notification was handled. * This is called at a time when it is not OK to change the geometry of * this widget or of other widgets. */ - virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) { return false; } + virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion); /** * Indicates that a paint occurred. * This is called at a time when it is OK to change the geometry of * this widget or of other widgets. * Must be called after every call to PaintWindow. */ - virtual void DidPaintWindow() { } + virtual void DidPaintWindow(); /** * Request that layout schedules a repaint on the next refresh driver tick. */ - virtual void RequestRepaint() { } + virtual void RequestRepaint(); /** * Handle an event. */ virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent, - bool aUseAttachedEvents) - { - return nsEventStatus_eIgnore; - } + bool aUseAttachedEvents); }; #endif
--- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -2803,16 +2803,24 @@ nsWindow::GetDPI() if (heightInches < 0.25) { // Something's broken, but we'd better not crash. return 96.0f; } return float(rootWindow->height()/heightInches); } +nsEventStatus +nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) +{ + nsEventStatus status; + DispatchEvent(aEvent, status); + return status; +} + void nsWindow::DispatchActivateEvent(void) { if (mWidgetListener) mWidgetListener->WindowActivated(); } void @@ -3165,8 +3173,42 @@ nsWindow::GetGLFrameBufferFormat() { if (mLayerManager && mLayerManager->GetBackendType() == mozilla::layers::LAYERS_OPENGL) { return MozQGLWidgetWrapper::isRGBAContext() ? LOCAL_GL_RGBA : LOCAL_GL_RGB; } return LOCAL_GL_NONE; } +void +nsWindow::ProcessMotionEvent() +{ + if (mPinchEvent.needDispatch) { + double distance = DistanceBetweenPoints(mPinchEvent.centerPoint, + mPinchEvent.touchPoint); + distance *= 2; + mPinchEvent.delta = distance - mPinchEvent.prevDistance; + nsIntPoint centerPoint(mPinchEvent.centerPoint.x(), + mPinchEvent.centerPoint.y()); + DispatchGestureEvent(NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, + 0, mPinchEvent.delta, centerPoint); + mPinchEvent.prevDistance = distance; + } + if (mMoveEvent.needDispatch) { + WidgetMouseEvent event(true, NS_MOUSE_MOVE, this, + WidgetMouseEvent::eReal); + + event.refPoint.x = nscoord(mMoveEvent.pos.x()); + event.refPoint.y = nscoord(mMoveEvent.pos.y()); + + event.InitBasicModifiers(mMoveEvent.modifiers & Qt::ControlModifier, + mMoveEvent.modifiers & Qt::AltModifier, + mMoveEvent.modifiers & Qt::ShiftModifier, + mMoveEvent.modifiers & Qt::MetaModifier); + event.clickCount = 0; + + DispatchEvent(&event); + mMoveEvent.needDispatch = false; + } + + mTimerStarted = false; +} +
--- a/widget/qt/nsWindow.h +++ b/widget/qt/nsWindow.h @@ -11,17 +11,17 @@ #include <QKeyEvent> #include <QGestureEvent> #include <qgraphicswidget.h> #include <QTime> #include "nsAutoPtr.h" #include "nsBaseWidget.h" -#include "mozilla/MouseEvents.h" +#include "mozilla/EventForwards.h" #include "nsWeakReference.h" #include "nsGkAtoms.h" #include "nsIIdleServiceInternal.h" #include "nsIRunnable.h" #include "nsThreadUtils.h" @@ -178,22 +178,17 @@ public: // event handling code void DispatchActivateEvent(void); void DispatchDeactivateEvent(void); void DispatchActivateEventOnTopLevelWindow(void); void DispatchDeactivateEventOnTopLevelWindow(void); void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus); - nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent) - { - nsEventStatus status; - DispatchEvent(aEvent, status); - return status; - } + nsEventStatus DispatchEvent(mozilla::WidgetGUIEvent* aEvent); // Some of the nsIWidget methods virtual bool IsEnabled() const; // called when we are destroyed void OnDestroy(void); // called to check and see if a widget's dimensions are sane @@ -373,45 +368,17 @@ private: *flag &= ~mask; } int32_t mQCursor; // Call this function when the users activity is the direct cause of an // event (like a keypress or mouse click). void UserActivity(); - inline void ProcessMotionEvent() { - if (mPinchEvent.needDispatch) { - double distance = DistanceBetweenPoints(mPinchEvent.centerPoint, mPinchEvent.touchPoint); - distance *= 2; - mPinchEvent.delta = distance - mPinchEvent.prevDistance; - nsIntPoint centerPoint(mPinchEvent.centerPoint.x(), mPinchEvent.centerPoint.y()); - DispatchGestureEvent(NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, - 0, mPinchEvent.delta, centerPoint); - mPinchEvent.prevDistance = distance; - } - if (mMoveEvent.needDispatch) { - WidgetMouseEvent event(true, NS_MOUSE_MOVE, this, - WidgetMouseEvent::eReal); - - event.refPoint.x = nscoord(mMoveEvent.pos.x()); - event.refPoint.y = nscoord(mMoveEvent.pos.y()); - - event.InitBasicModifiers(mMoveEvent.modifiers & Qt::ControlModifier, - mMoveEvent.modifiers & Qt::AltModifier, - mMoveEvent.modifiers & Qt::ShiftModifier, - mMoveEvent.modifiers & Qt::MetaModifier); - event.clickCount = 0; - - DispatchEvent(&event); - mMoveEvent.needDispatch = false; - } - - mTimerStarted = false; - } + inline void ProcessMotionEvent(); void DispatchMotionToMainThread() { if (!mTimerStarted) { nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &nsWindow::ProcessMotionEvent); NS_DispatchToMainThread(event); mTimerStarted = true; }
--- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -90,16 +90,48 @@ public: PRUnichar GetCompositeChar(PRUnichar aBaseChar) const; }; /***************************************************************************** * mozilla::widget::ModifierKeyState *****************************************************************************/ +ModifierKeyState::ModifierKeyState() +{ + Update(); +} + +ModifierKeyState::ModifierKeyState(bool aIsShiftDown, + bool aIsControlDown, + bool aIsAltDown) +{ + Update(); + Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_ALTGRAPH); + Modifiers modifiers = 0; + if (aIsShiftDown) { + modifiers |= MODIFIER_SHIFT; + } + if (aIsControlDown) { + modifiers |= MODIFIER_CONTROL; + } + if (aIsAltDown) { + modifiers |= MODIFIER_ALT; + } + if (modifiers) { + Set(modifiers); + } +} + +ModifierKeyState::ModifierKeyState(Modifiers aModifiers) : + mModifiers(aModifiers) +{ + EnsureAltGr(); +} + void ModifierKeyState::Update() { mModifiers = 0; if (IS_VK_DOWN(VK_SHIFT)) { mModifiers |= MODIFIER_SHIFT; } if (IS_VK_DOWN(VK_CONTROL)) { @@ -120,16 +152,32 @@ ModifierKeyState::Update() if (::GetKeyState(VK_SCROLL) & 1) { mModifiers |= MODIFIER_SCROLLLOCK; } EnsureAltGr(); } void +ModifierKeyState::Unset(Modifiers aRemovingModifiers) +{ + mModifiers &= ~aRemovingModifiers; + // Note that we don't need to unset AltGr flag here automatically. + // For nsEditor, we need to remove Alt and Control flags but AltGr isn't + // checked in nsEditor, so, it can be kept. +} + +void +ModifierKeyState::Set(Modifiers aAddingModifiers) +{ + mModifiers |= aAddingModifiers; + EnsureAltGr(); +} + +void ModifierKeyState::InitInputEvent(WidgetInputEvent& aInputEvent) const { aInputEvent.modifiers = mModifiers; switch(aInputEvent.eventStructType) { case NS_MOUSE_EVENT: case NS_MOUSE_SCROLL_EVENT: case NS_WHEEL_EVENT: @@ -165,16 +213,82 @@ ModifierKeyState::InitMouseEvent(WidgetI if (::GetKeyState(VK_XBUTTON1) < 0) { mouseEvent.buttons |= WidgetMouseEvent::e4thButtonFlag; } if (::GetKeyState(VK_XBUTTON2) < 0) { mouseEvent.buttons |= WidgetMouseEvent::e5thButtonFlag; } } +bool +ModifierKeyState::IsShift() const +{ + return (mModifiers & MODIFIER_SHIFT) != 0; +} + +bool +ModifierKeyState::IsControl() const +{ + return (mModifiers & MODIFIER_CONTROL) != 0; +} + +bool +ModifierKeyState::IsAlt() const +{ + return (mModifiers & MODIFIER_ALT) != 0; +} + +bool +ModifierKeyState::IsAltGr() const +{ + return IsControl() && IsAlt(); +} + +bool +ModifierKeyState::IsWin() const +{ + return (mModifiers & MODIFIER_OS) != 0; +} + +bool +ModifierKeyState::IsCapsLocked() const +{ + return (mModifiers & MODIFIER_CAPSLOCK) != 0; +} + +bool +ModifierKeyState::IsNumLocked() const +{ + return (mModifiers & MODIFIER_NUMLOCK) != 0; +} + +bool +ModifierKeyState::IsScrollLocked() const +{ + return (mModifiers & MODIFIER_SCROLLLOCK) != 0; +} + +Modifiers +ModifierKeyState::GetModifiers() const +{ + return mModifiers; +} + +void +ModifierKeyState::EnsureAltGr() +{ + // If both Control key and Alt key are pressed, it means AltGr is pressed. + // Ideally, we should check whether the current keyboard layout has AltGr + // or not. However, setting AltGr flags for keyboard which doesn't have + // AltGr must not be serious bug. So, it should be OK for now. + if (IsAltGr()) { + mModifiers |= MODIFIER_ALTGRAPH; + } +} + /***************************************************************************** * mozilla::widget::UniCharsAndModifiers *****************************************************************************/ void UniCharsAndModifiers::Append(PRUnichar aUniChar, Modifiers aModifiers) { MOZ_ASSERT(mLength < 5); @@ -231,16 +345,60 @@ UniCharsAndModifiers::operator+(const Un result += aOther; return result; } /***************************************************************************** * mozilla::widget::VirtualKey *****************************************************************************/ +// static +VirtualKey::ShiftState +VirtualKey::ModifiersToShiftState(Modifiers aModifiers) +{ + ShiftState state = 0; + if (aModifiers & MODIFIER_SHIFT) { + state |= STATE_SHIFT; + } + if (aModifiers & MODIFIER_CONTROL) { + state |= STATE_CONTROL; + } + if (aModifiers & MODIFIER_ALT) { + state |= STATE_ALT; + } + if (aModifiers & MODIFIER_CAPSLOCK) { + state |= STATE_CAPSLOCK; + } + return state; +} + +// static +Modifiers +VirtualKey::ShiftStateToModifiers(ShiftState aShiftState) +{ + Modifiers modifiers = 0; + if (aShiftState & STATE_SHIFT) { + modifiers |= MODIFIER_SHIFT; + } + if (aShiftState & STATE_CONTROL) { + modifiers |= MODIFIER_CONTROL; + } + if (aShiftState & STATE_ALT) { + modifiers |= MODIFIER_ALT; + } + if (aShiftState & STATE_CAPSLOCK) { + modifiers |= MODIFIER_CAPSLOCK; + } + if ((modifiers & (MODIFIER_ALT | MODIFIER_CONTROL)) == + (MODIFIER_ALT | MODIFIER_CONTROL)) { + modifiers |= MODIFIER_ALTGRAPH; + } + return modifiers; +} + inline PRUnichar VirtualKey::GetCompositeChar(ShiftState aShiftState, PRUnichar aBaseChar) const { return mShiftStates[aShiftState].DeadKey.Table->GetCompositeChar(aBaseChar); } const DeadKeyTable* VirtualKey::MatchingDeadKeyTable(const DeadKeyEntry* aDeadKeyArray, @@ -748,16 +906,22 @@ PRUnichar NativeKey::ComputeUnicharFromScanCode() const { return static_cast<PRUnichar>( ::MapVirtualKeyEx(ComputeVirtualKeyCodeFromScanCode(), MAPVK_VK_TO_CHAR, mKeyboardLayout)); } void +NativeKey::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const +{ + InitKeyEvent(aKeyEvent, mModKeyState); +} + +void NativeKey::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, const ModifierKeyState& aModKeyState) const { nsIntPoint point(0, 0); mWidget->InitEvent(aKeyEvent, &point); switch (aKeyEvent.message) { case NS_KEY_DOWN:
--- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -6,16 +6,17 @@ #ifndef KeyboardLayout_h__ #define KeyboardLayout_h__ #include "nscore.h" #include "nsAutoPtr.h" #include "nsString.h" #include "nsWindowBase.h" #include "nsWindowDefs.h" +#include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" #include <windows.h> #define NS_NUM_OF_KEYS 70 #define VK_OEM_1 0xBA // ';:' for US #define VK_OEM_PLUS 0xBB // '+' any country #define VK_OEM_COMMA 0xBC @@ -49,94 +50,46 @@ static const uint32_t sModifierKeyMap[][ { nsIWidget::CTRL_L, VK_CONTROL, VK_LCONTROL }, { nsIWidget::CTRL_R, VK_CONTROL, VK_RCONTROL }, { nsIWidget::ALT_L, VK_MENU, VK_LMENU }, { nsIWidget::ALT_R, VK_MENU, VK_RMENU } }; class KeyboardLayout; -class ModifierKeyState { +class ModifierKeyState +{ public: - ModifierKeyState() - { - Update(); - } + ModifierKeyState(); + ModifierKeyState(bool aIsShiftDown, bool aIsControlDown, bool aIsAltDown); + ModifierKeyState(Modifiers aModifiers); - ModifierKeyState(bool aIsShiftDown, bool aIsControlDown, bool aIsAltDown) - { - Update(); - Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_ALTGRAPH); - Modifiers modifiers = 0; - if (aIsShiftDown) { - modifiers |= MODIFIER_SHIFT; - } - if (aIsControlDown) { - modifiers |= MODIFIER_CONTROL; - } - if (aIsAltDown) { - modifiers |= MODIFIER_ALT; - } - if (modifiers) { - Set(modifiers); - } - } + MOZ_ALWAYS_INLINE void Update(); - ModifierKeyState(Modifiers aModifiers) : - mModifiers(aModifiers) - { - EnsureAltGr(); - } - - void Update(); - - void Unset(Modifiers aRemovingModifiers) - { - mModifiers &= ~aRemovingModifiers; - // Note that we don't need to unset AltGr flag here automatically. - // For nsEditor, we need to remove Alt and Control flags but AltGr isn't - // checked in nsEditor, so, it can be kept. - } - - void Set(Modifiers aAddingModifiers) - { - mModifiers |= aAddingModifiers; - EnsureAltGr(); - } + MOZ_ALWAYS_INLINE void Unset(Modifiers aRemovingModifiers); + MOZ_ALWAYS_INLINE void Set(Modifiers aAddingModifiers); void InitInputEvent(WidgetInputEvent& aInputEvent) const; - bool IsShift() const { return (mModifiers & MODIFIER_SHIFT) != 0; } - bool IsControl() const { return (mModifiers & MODIFIER_CONTROL) != 0; } - bool IsAlt() const { return (mModifiers & MODIFIER_ALT) != 0; } - bool IsAltGr() const { return IsControl() && IsAlt(); } - bool IsWin() const { return (mModifiers & MODIFIER_OS) != 0; } + MOZ_ALWAYS_INLINE bool IsShift() const; + MOZ_ALWAYS_INLINE bool IsControl() const; + MOZ_ALWAYS_INLINE bool IsAlt() const; + MOZ_ALWAYS_INLINE bool IsAltGr() const; + MOZ_ALWAYS_INLINE bool IsWin() const; - bool IsCapsLocked() const { return (mModifiers & MODIFIER_CAPSLOCK) != 0; } - bool IsNumLocked() const { return (mModifiers & MODIFIER_NUMLOCK) != 0; } - bool IsScrollLocked() const - { - return (mModifiers & MODIFIER_SCROLLLOCK) != 0; - } + MOZ_ALWAYS_INLINE bool IsCapsLocked() const; + MOZ_ALWAYS_INLINE bool IsNumLocked() const; + MOZ_ALWAYS_INLINE bool IsScrollLocked() const; - Modifiers GetModifiers() const { return mModifiers; } + MOZ_ALWAYS_INLINE Modifiers GetModifiers() const; private: Modifiers mModifiers; - void EnsureAltGr() - { - // If both Control key and Alt key are pressed, it means AltGr is pressed. - // Ideally, we should check whether the current keyboard layout has AltGr - // or not. However, setting AltGr flags for keyboard which doesn't have - // AltGr must not be serious bug. So, it should be OK for now. - if (IsAltGr()) { - mModifiers |= MODIFIER_ALTGRAPH; - } - } + MOZ_ALWAYS_INLINE void EnsureAltGr(); void InitMouseEvent(WidgetInputEvent& aMouseEvent) const; }; struct UniCharsAndModifiers { // Dead-key + up to 4 characters PRUnichar mChars[5]; @@ -191,55 +144,18 @@ public: STATE_SHIFT = 0x01, STATE_CONTROL = 0x02, STATE_ALT = 0x04, STATE_CAPSLOCK = 0x08 }; typedef uint8_t ShiftState; - static ShiftState ModifiersToShiftState(Modifiers aModifiers) - { - ShiftState state = 0; - if (aModifiers & MODIFIER_SHIFT) { - state |= STATE_SHIFT; - } - if (aModifiers & MODIFIER_CONTROL) { - state |= STATE_CONTROL; - } - if (aModifiers & MODIFIER_ALT) { - state |= STATE_ALT; - } - if (aModifiers & MODIFIER_CAPSLOCK) { - state |= STATE_CAPSLOCK; - } - return state; - } - - static Modifiers ShiftStateToModifiers(ShiftState aShiftState) - { - Modifiers modifiers = 0; - if (aShiftState & STATE_SHIFT) { - modifiers |= MODIFIER_SHIFT; - } - if (aShiftState & STATE_CONTROL) { - modifiers |= MODIFIER_CONTROL; - } - if (aShiftState & STATE_ALT) { - modifiers |= MODIFIER_ALT; - } - if (aShiftState & STATE_CAPSLOCK) { - modifiers |= MODIFIER_CAPSLOCK; - } - if ((modifiers & (MODIFIER_ALT | MODIFIER_CONTROL)) == - (MODIFIER_ALT | MODIFIER_CONTROL)) { - modifiers |= MODIFIER_ALTGRAPH; - } - return modifiers; - } + static ShiftState ModifiersToShiftState(Modifiers aModifiers); + static Modifiers ShiftStateToModifiers(ShiftState aShiftState); private: union KeyShiftState { struct { PRUnichar Chars[4]; } Normal; @@ -423,20 +339,17 @@ private: */ PRUnichar ComputeUnicharFromScanCode() const; /** * Initializes the aKeyEvent with the information stored in the instance. */ void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, const ModifierKeyState& aModKeyState) const; - void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const - { - InitKeyEvent(aKeyEvent, mModKeyState); - } + void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent) const; /** * Dispatches the key event. Returns true if the event is consumed. * Otherwise, false. */ bool DispatchKeyEvent(WidgetKeyboardEvent& aKeyEvent, const MSG* aMsgSentToPlugin = nullptr) const;
--- a/widget/windows/moz.build +++ b/widget/windows/moz.build @@ -56,16 +56,17 @@ CPP_SOURCES += [ 'nsScreenManagerWin.cpp', 'nsScreenWin.cpp', 'nsSound.cpp', 'nsToolkit.cpp', 'nsUXThemeData.cpp', 'nsWidgetFactory.cpp', 'nsWinGesture.cpp', 'nsWindow.cpp', + 'nsWindowBase.cpp', 'nsWindowDbg.cpp', 'nsWindowGfx.cpp', ] if CONFIG['MOZ_CRASHREPORTER']: CPP_SOURCES += [ 'LSPAnnotator.cpp', ]
--- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -8,17 +8,17 @@ #include "nsAutoPtr.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsITimer.h" #include "nsIWidget.h" #include "nsWindowBase.h" #include "mozilla/Attributes.h" -#include "mozilla/TextEvents.h" +#include "mozilla/TextRange.h" #include <msctf.h> #include <textstor.h> // GUID_PROP_INPUTSCOPE is declared in inputscope.h using INIT_GUID. // With initguid.h, we get its instance instead of extern declaration. #ifdef INPUTSCOPE_INIT_GUID #include <initguid.h>
--- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -167,16 +167,18 @@ #include "nsCrashOnException.h" #include "nsIXULRuntime.h" #include "nsIContent.h" #include "mozilla/HangMonitor.h" #include "WinIMEHandler.h" +#include "npapi.h" + using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::layers; using namespace mozilla::widget; /************************************************************** ************************************************************** **
new file mode 100644 --- /dev/null +++ b/widget/windows/nsWindowBase.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 4; 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 "nsWindowBase.h" + +#include "mozilla/MiscEvents.h" +#include "npapi.h" + +using namespace mozilla; + +bool +nsWindowBase::DispatchPluginEvent(const MSG& aMsg) +{ + if (!PluginHasFocus()) { + return false; + } + WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this); + nsIntPoint point(0, 0); + InitEvent(pluginEvent, &point); + NPEvent npEvent; + npEvent.event = aMsg.message; + npEvent.wParam = aMsg.wParam; + npEvent.lParam = aMsg.lParam; + pluginEvent.pluginEvent = &npEvent; + pluginEvent.retargetToFocusedDocument = true; + return DispatchWindowEvent(&pluginEvent); +}
--- a/widget/windows/nsWindowBase.h +++ b/widget/windows/nsWindowBase.h @@ -1,19 +1,18 @@ /* -*- Mode: C++; tab-width: 4; 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 nsWindowBase_h_ #define nsWindowBase_h_ -#include "mozilla/MiscEvents.h" +#include "mozilla/EventForwards.h" #include "nsBaseWidget.h" -#include "npapi.h" #include <windows.h> /* * nsWindowBase - Base class of common methods other classes need to access * in both win32 and winrt window classes. */ class nsWindowBase : public nsBaseWidget { @@ -54,32 +53,17 @@ public: * is called by KeyboardLayout to dispatch gecko events. * Returns true if it's consumed. Otherwise, false. */ virtual bool DispatchKeyboardEvent(mozilla::WidgetGUIEvent* aEvent) = 0; /* * Default dispatch of a plugin event. */ - virtual bool DispatchPluginEvent(const MSG &aMsg) - { - if (!PluginHasFocus()) { - return false; - } - mozilla::WidgetPluginEvent pluginEvent(true, NS_PLUGIN_INPUT_EVENT, this); - nsIntPoint point(0, 0); - InitEvent(pluginEvent, &point); - NPEvent npEvent; - npEvent.event = aMsg.message; - npEvent.wParam = aMsg.wParam; - npEvent.lParam = aMsg.lParam; - pluginEvent.pluginEvent = (void *)&npEvent; - pluginEvent.retargetToFocusedDocument = true; - return DispatchWindowEvent(&pluginEvent); - } + virtual bool DispatchPluginEvent(const MSG& aMsg); /* * Returns true if a plugin has focus on this widget. Otherwise, false. */ virtual bool PluginHasFocus() const MOZ_FINAL { return (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); }
--- a/widget/xpwidgets/moz.build +++ b/widget/xpwidgets/moz.build @@ -24,16 +24,17 @@ CPP_SOURCES += [ 'nsBaseDragService.cpp', 'nsBaseScreen.cpp', 'nsBaseWidget.cpp', 'nsClipboardHelper.cpp', 'nsClipboardPrivacyHandler.cpp', 'nsFilePickerProxy.cpp', 'nsHTMLFormatConverter.cpp', 'nsIdleService.cpp', + 'nsIWidgetListener.cpp', 'nsPrimitiveHelpers.cpp', 'nsPrintOptionsImpl.cpp', 'nsPrintSession.cpp', 'nsPrintSettingsImpl.cpp', 'nsTransferable.cpp', 'nsXPLookAndFeel.cpp', ]
new file mode 100644 --- /dev/null +++ b/widget/xpwidgets/nsIWidgetListener.cpp @@ -0,0 +1,114 @@ +/* -*- 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 "nsIWidgetListener.h" + +#include "nsRegion.h" +#include "nsView.h" +#include "nsIPresShell.h" +#include "nsIWidget.h" +#include "nsIXULWindow.h" + +#include "mozilla/BasicEvents.h" + +using namespace mozilla; + +nsIXULWindow* +nsIWidgetListener::GetXULWindow() +{ + return nullptr; +} + +nsView* +nsIWidgetListener::GetView() +{ + return nullptr; +} + +nsIPresShell* +nsIWidgetListener::GetPresShell() +{ + return nullptr; +} + +bool +nsIWidgetListener::WindowMoved(nsIWidget* aWidget, + int32_t aX, + int32_t aY) +{ + return false; +} + +bool +nsIWidgetListener::WindowResized(nsIWidget* aWidget, + int32_t aWidth, + int32_t aHeight) +{ + return false; +} + +void +nsIWidgetListener::SizeModeChanged(nsSizeMode aSizeMode) +{ +} + +bool +nsIWidgetListener::ZLevelChanged(bool aImmediate, + nsWindowZ* aPlacement, + nsIWidget* aRequestBelow, + nsIWidget** aActualBelow) +{ + return false; +} + +void +nsIWidgetListener::WindowActivated() +{ +} + +void +nsIWidgetListener::WindowDeactivated() +{ +} + +void +nsIWidgetListener::OSToolbarButtonPressed() +{ +} + +bool +nsIWidgetListener::RequestWindowClose(nsIWidget* aWidget) +{ + return false; +} + +void +nsIWidgetListener::WillPaintWindow(nsIWidget* aWidget) +{ +} + +bool +nsIWidgetListener::PaintWindow(nsIWidget* aWidget, + nsIntRegion aRegion) +{ + return false; +} + +void +nsIWidgetListener::DidPaintWindow() +{ +} + +void +nsIWidgetListener::RequestRepaint() +{ +} + +nsEventStatus +nsIWidgetListener::HandleEvent(WidgetGUIEvent* aEvent, + bool aUseAttachedEvents) +{ + return nsEventStatus_eIgnore; +}
--- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -1,22 +1,23 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" -interface nsISimpleEnumerator; +interface nsICancelableRunnable; +interface nsIDOMWindow; interface nsIRunnable; -interface nsICancelableRunnable; +interface nsISimpleEnumerator; /* - * Memory reporters measure Firefox's memory usage. They are mainly used to + * Memory reporters measure Firefox's memory usage. They are primarily used to * generate the about:memory page. You should read * https://wiki.mozilla.org/Memory_Reporting before writing a memory * reporter. */ [scriptable, function, uuid(3a61be3b-b93b-461a-a4f8-388214f558b1)] interface nsIMemoryReporterCallback : nsISupports { @@ -303,22 +304,42 @@ interface nsIMemoryReporterManager : nsI [infallible] readonly attribute boolean hasMozMallocUsableSize; /* * Run a series of GC/CC's in an attempt to minimize the application's memory * usage. When we're finished, we invoke the given runnable if it's not * null. Returns a reference to the runnable used for carrying out the task. */ nsICancelableRunnable minimizeMemoryUsage(in nsIRunnable callback); + + /* + * Measure the memory that is known to be owned by this tab, split up into + * several broad categories. Note that this will be an underestimate of the + * true number, due to imperfect memory reporter coverage (corresponding to + * about:memory's "heap-unclassified"), and due to some memory shared between + * tabs not being counted. + * + * The time taken for the measurement (split into JS and non-JS parts) is + * also returned. + */ + void sizeOfTab(in nsIDOMWindow window, + out int64_t jsObjectsSize, out int64_t jsStringsSize, + out int64_t jsOtherSize, out int64_t domSize, + out int64_t styleSize, out int64_t otherSize, + out int64_t totalSize, + out double jsMilliseconds, out double nonJSMilliseconds); }; %{C++ +#include "js/TypeDecls.h" #include "nsStringGlue.h" +class nsPIDOMWindow; + // Note that the memory reporters are held in an nsCOMArray, which means // that individual reporters should be referenced with |nsIMemoryReporter *| // instead of nsCOMPtr<nsIMemoryReporter>. XPCOM_API(nsresult) NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter); XPCOM_API(nsresult) NS_UnregisterMemoryReporter(nsIMemoryReporter* aReporter); namespace mozilla { @@ -350,16 +371,31 @@ DECL_UNREGISTER_DISTINGUISHED_AMOUNT(Sto DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsVirtual) DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsPhysical) DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, GhostWindows) #undef DECL_REGISTER_DISTINGUISHED_AMOUNT #undef DECL_UNREGISTER_DISTINGUISHED_AMOUNT +// Likewise for per-tab measurement. + +typedef nsresult (*JSSizeOfTabFn)(JSObject* aObj, + size_t* aJsObjectsSize, + size_t* aJsStringSize, + size_t* aJsPrivateSize, + size_t* aJsOtherSize); +typedef nsresult (*NonJSSizeOfTabFn)(nsPIDOMWindow* aWindow, + size_t* aDomSize, + size_t* aStyleSize, + size_t* aOtherSize); + +nsresult RegisterJSSizeOfTab(JSSizeOfTabFn aSizeOfTabFn); +nsresult RegisterNonJSSizeOfTab(NonJSSizeOfTabFn aSizeOfTabFn); + } #if defined(MOZ_DMD) namespace mozilla { namespace dmd { // This runs all the memory reporters but does nothing with the results; i.e. // it does the minimal amount of work possible for DMD to do its thing. void RunReporters();
--- a/xpcom/base/nsMemoryInfoDumper.cpp +++ b/xpcom/base/nsMemoryInfoDumper.cpp @@ -605,29 +605,30 @@ namespace mozilla { #define DUMP(o, s) \ do { \ nsresult rv = (o)->Write(s); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) static nsresult -DumpReport(nsIGZFileWriter *aWriter, bool aIsFirst, +DumpReport(nsIGZFileWriter *aWriter, bool *aIsFirstPtr, const nsACString &aProcess, const nsACString &aPath, int32_t aKind, int32_t aUnits, int64_t aAmount, const nsACString &aDescription) { - DUMP(aWriter, aIsFirst ? "[" : ","); - // We only want to dump reports for this process. If |aProcess| is // non-nullptr that means we've received it from another process in response // to a "child-memory-reporter-request" event; ignore such reports. if (!aProcess.IsEmpty()) { return NS_OK; } + DUMP(aWriter, *aIsFirstPtr ? "[" : ","); + *aIsFirstPtr = false; + // Generate the process identifier, which is of the form "$PROCESS_NAME // (pid $PID)", or just "(pid $PID)" if we don't have a process name. If // we're the main process, we let $PROCESS_NAME be "Main Process". nsAutoCString processId; if (XRE_GetProcessType() == GeckoProcessType_Default) { // We're the main process. processId.AssignLiteral("Main Process "); } else if (ContentChild *cc = ContentChild::GetSingleton()) { @@ -673,37 +674,32 @@ DumpReport(nsIGZFileWriter *aWriter, boo return NS_OK; } class DumpReporterCallback MOZ_FINAL : public nsIMemoryReporterCallback { public: NS_DECL_ISUPPORTS - DumpReporterCallback(bool* aIsFirstPtr) : mIsFirstPtr(aIsFirstPtr) {} + DumpReporterCallback() : mIsFirst(true) {} NS_IMETHOD Callback(const nsACString &aProcess, const nsACString &aPath, int32_t aKind, int32_t aUnits, int64_t aAmount, const nsACString &aDescription, nsISupports *aData) { nsCOMPtr<nsIGZFileWriter> writer = do_QueryInterface(aData); NS_ENSURE_TRUE(writer, NS_ERROR_FAILURE); - // The |isFirst = false| assumes that at least one single reporter is - // present and so will have been processed in - // DumpProcessMemoryReportsToGZFileWriter() below. - bool isFirst = *mIsFirstPtr; - *mIsFirstPtr = false; - return DumpReport(writer, isFirst, aProcess, aPath, aKind, aUnits, aAmount, - aDescription); + return DumpReport(writer, &mIsFirst, aProcess, aPath, aKind, aUnits, + aAmount, aDescription); } private: - bool* mIsFirstPtr; + bool mIsFirst; }; NS_IMPL_ISUPPORTS1(DumpReporterCallback, nsIMemoryReporterCallback) } // namespace mozilla static void MakeFilename(const char *aPrefix, const nsAString &aIdentifier, @@ -812,21 +808,20 @@ DumpProcessMemoryReportsToGZFileWriter(n do_GetService("@mozilla.org/memory-reporter-manager;1"); NS_ENSURE_STATE(mgr); DUMP(aWriter, mgr->GetHasMozMallocUsableSize() ? "true" : "false"); DUMP(aWriter, ",\n"); DUMP(aWriter, " \"reports\": "); // Process reporters. - bool isFirst = true; bool more; nsCOMPtr<nsISimpleEnumerator> e; mgr->EnumerateReporters(getter_AddRefs(e)); - nsRefPtr<DumpReporterCallback> cb = new DumpReporterCallback(&isFirst); + nsRefPtr<DumpReporterCallback> cb = new DumpReporterCallback(); while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) { nsCOMPtr<nsIMemoryReporter> r; e->GetNext(getter_AddRefs(r)); r->CollectReports(cb, aWriter); } DUMP(aWriter, "\n ]\n}\n");
--- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -7,17 +7,20 @@ #include "nsAtomTable.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsCOMArray.h" #include "nsServiceManagerUtils.h" #include "nsMemoryReporterManager.h" #include "nsISimpleEnumerator.h" #include "nsThreadUtils.h" +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" #include "nsIObserverService.h" +#include "nsIGlobalObject.h" #if defined(XP_LINUX) #include "nsMemoryInfoDumper.h" #endif #include "mozilla/Attributes.h" #include "mozilla/PodOperations.h" #include "mozilla/Services.h" #include "mozilla/Telemetry.h" @@ -840,16 +843,17 @@ HashtableEnumerator::GetNext(nsISupports } // anonymous namespace nsMemoryReporterManager::nsMemoryReporterManager() : mMutex("nsMemoryReporterManager::mMutex"), mIsRegistrationBlocked(false) { PodZero(&mAmountFns); + PodZero(&mSizeOfTabFns); } nsMemoryReporterManager::~nsMemoryReporterManager() { } NS_IMETHODIMP nsMemoryReporterManager::EnumerateReporters(nsISimpleEnumerator** aResult) @@ -1262,16 +1266,66 @@ nsMemoryReporterManager::MinimizeMemoryU nsRefPtr<nsICancelableRunnable> runnable = new MinimizeMemoryUsageRunnable(aCallback); NS_ADDREF(*aResult = runnable); return NS_DispatchToMainThread(runnable); } +NS_IMETHODIMP +nsMemoryReporterManager::SizeOfTab(nsIDOMWindow* aTopWindow, + int64_t* aJSObjectsSize, + int64_t* aJSStringsSize, + int64_t* aJSOtherSize, + int64_t* aDomSize, + int64_t* aStyleSize, + int64_t* aOtherSize, + int64_t* aTotalSize, + double* aJSMilliseconds, + double* aNonJSMilliseconds) +{ + nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aTopWindow); + nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(aTopWindow); + NS_ENSURE_TRUE(!!global && !!piWindow, NS_ERROR_FAILURE); + + TimeStamp t1 = TimeStamp::Now(); + + // Measure JS memory consumption (and possibly some non-JS consumption, via + // |jsPrivateSize|). + size_t jsObjectsSize, jsStringsSize, jsPrivateSize, jsOtherSize; + nsresult rv = mSizeOfTabFns.mJS(global->GetGlobalJSObject(), + &jsObjectsSize, &jsStringsSize, + &jsPrivateSize, &jsOtherSize); + NS_ENSURE_SUCCESS(rv, rv); + + TimeStamp t2 = TimeStamp::Now(); + + // Measure non-JS memory consumption. + size_t domSize, styleSize, otherSize; + mSizeOfTabFns.mNonJS(piWindow, &domSize, &styleSize, &otherSize); + + TimeStamp t3 = TimeStamp::Now(); + + *aTotalSize = 0; + #define DO(aN, n) { *aN = (n); *aTotalSize += (n); } + DO(aJSObjectsSize, jsObjectsSize); + DO(aJSStringsSize, jsStringsSize); + DO(aJSOtherSize, jsOtherSize); + DO(aDomSize, jsPrivateSize + domSize); + DO(aStyleSize, styleSize); + DO(aOtherSize, otherSize); + #undef DO + + *aJSMilliseconds = (t2 - t1).ToMilliseconds(); + *aNonJSMilliseconds = (t3 - t2).ToMilliseconds(); + + return NS_OK; +} + // Most memory reporters don't need thread safety, but some do. Make them all // thread-safe just to be safe. Memory reporters are created and destroyed // infrequently enough that the performance cost should be negligible. NS_IMPL_ISUPPORTS1(MemoryUniReporter, nsIMemoryReporter) nsresult NS_RegisterMemoryReporter(nsIMemoryReporter* aReporter) { @@ -1289,44 +1343,41 @@ NS_UnregisterMemoryReporter(nsIMemoryRep if (!mgr) { return NS_ERROR_FAILURE; } return mgr->UnregisterReporter(aReporter); } namespace mozilla { +#define GET_MEMORY_REPORTER_MANAGER(mgr) \ + nsCOMPtr<nsIMemoryReporterManager> imgr = \ + do_GetService("@mozilla.org/memory-reporter-manager;1"); \ + nsRefPtr<nsMemoryReporterManager> mgr = \ + static_cast<nsMemoryReporterManager*>(imgr.get()); \ + if (!mgr) { \ + return NS_ERROR_FAILURE; \ + } + // Macro for generating functions that register distinguished amount functions // with the memory reporter manager. #define DEFINE_REGISTER_DISTINGUISHED_AMOUNT(kind, name) \ nsresult \ Register##name##DistinguishedAmount(kind##AmountFn aAmountFn) \ { \ - nsCOMPtr<nsIMemoryReporterManager> imgr = \ - do_GetService("@mozilla.org/memory-reporter-manager;1"); \ - nsRefPtr<nsMemoryReporterManager> mgr = \ - static_cast<nsMemoryReporterManager*>(imgr.get()); \ - if (!mgr) { \ - return NS_ERROR_FAILURE; \ - } \ + GET_MEMORY_REPORTER_MANAGER(mgr) \ mgr->mAmountFns.m##name = aAmountFn; \ return NS_OK; \ } #define DEFINE_UNREGISTER_DISTINGUISHED_AMOUNT(name) \ nsresult \ Unregister##name##DistinguishedAmount() \ { \ - nsCOMPtr<nsIMemoryReporterManager> imgr = \ - do_GetService("@mozilla.org/memory-reporter-manager;1"); \ - nsRefPtr<nsMemoryReporterManager> mgr = \ - static_cast<nsMemoryReporterManager*>(imgr.get()); \ - if (!mgr) { \ - return NS_ERROR_FAILURE; \ - } \ + GET_MEMORY_REPORTER_MANAGER(mgr) \ mgr->mAmountFns.m##name = nullptr; \ return NS_OK; \ } DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeGCHeap) DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeTemporaryPeak) DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeCompartmentsSystem) DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeCompartmentsUser) @@ -1339,16 +1390,32 @@ DEFINE_UNREGISTER_DISTINGUISHED_AMOUNT(S DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsVirtual) DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsPhysical) DEFINE_REGISTER_DISTINGUISHED_AMOUNT(Infallible, GhostWindows) #undef DEFINE_REGISTER_DISTINGUISHED_AMOUNT #undef DEFINE_UNREGISTER_DISTINGUISHED_AMOUNT +#define DEFINE_REGISTER_SIZE_OF_TAB(name) \ + nsresult \ + Register##name##SizeOfTab(name##SizeOfTabFn aSizeOfTabFn) \ + { \ + GET_MEMORY_REPORTER_MANAGER(mgr) \ + mgr->mSizeOfTabFns.m##name = aSizeOfTabFn; \ + return NS_OK; \ + } + +DEFINE_REGISTER_SIZE_OF_TAB(JS); +DEFINE_REGISTER_SIZE_OF_TAB(NonJS); + +#undef DEFINE_REGISTER_SIZE_OF_TAB + +#undef GET_MEMORY_REPORTER_MANAGER + } #if defined(MOZ_DMD) namespace mozilla { namespace dmd { class NullReporterCallback : public nsIMemoryReporterCallback
--- a/xpcom/base/nsMemoryReporterManager.h +++ b/xpcom/base/nsMemoryReporterManager.h @@ -34,16 +34,23 @@ public: mozilla::InfallibleAmountFn mLowMemoryEventsVirtual; mozilla::InfallibleAmountFn mLowMemoryEventsPhysical; mozilla::InfallibleAmountFn mGhostWindows; }; AmountFns mAmountFns; + // Functions that measure per-tab memory consumption. + struct SizeOfTabFns { + mozilla::JSSizeOfTabFn mJS; + mozilla::NonJSSizeOfTabFn mNonJS; + }; + SizeOfTabFns mSizeOfTabFns; + private: nsresult RegisterReporterHelper(nsIMemoryReporter *aReporter, bool aForce); nsTHashtable<nsISupportsHashKey> mReporters; Mutex mMutex; bool mIsRegistrationBlocked; };
--- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -58,17 +58,17 @@ class Heap; // elements and has the following requirements: // // T MUST be safely memmove()'able. // T MUST define a copy-constructor. // T MAY define operator< for sorting. // T MAY define operator== for searching. // // (Note that the memmove requirement may be relaxed for certain types - see -// nsTArray_CopyElements below.) +// nsTArray_CopyChooser below.) // // For methods taking a Comparator instance, the Comparator must be a class // defining the following methods: // // class Comparator { // public: // /** @return True if the elements are equals; false otherwise. */ // bool Equals(const elem_type& a, const Item& b) const; @@ -568,17 +568,17 @@ struct AssignRangeAlgorithm<true, true> static void implementation(ElemType* elements, IndexType start, SizeType count, const Item *values) { memcpy(elements + start, values, count * sizeof(ElemType)); } }; // // Normally elements are copied with memcpy and memmove, but for some element -// types that is problematic. The nsTArray_CopyElements template class can be +// types that is problematic. The nsTArray_CopyChooser template class can be // specialized to ensure that copying calls constructors and destructors // instead, as is done below for JS::Heap<E> elements. // // // A class that defines how to copy elements using memcpy/memmove. // struct nsTArray_CopyWithMemutils @@ -653,24 +653,28 @@ struct nsTArray_CopyWithConstructors } } }; // // The default behaviour is to use memcpy/memmove for everything. // template <class E> -struct nsTArray_CopyElements : public nsTArray_CopyWithMemutils {}; +struct nsTArray_CopyChooser { + typedef nsTArray_CopyWithMemutils Type; +}; // // JS::Heap<E> elements require constructors/destructors to be called and so is // specialized here. // template <class E> -struct nsTArray_CopyElements<JS::Heap<E> > : public nsTArray_CopyWithConstructors<E> {}; +struct nsTArray_CopyChooser<JS::Heap<E> > { + typedef nsTArray_CopyWithConstructors<E> Type; +}; // // Base class for nsTArray_Impl that is templated on element type and derived // nsTArray_Impl class, to allow extra conversions to be added for specific // types. // template <class E, class Derived> struct nsTArray_TypedBase : public nsTArray_SafeElementAtHelper<E, Derived> {}; @@ -712,21 +716,21 @@ struct nsTArray_TypedBase<JS::Heap<E>, D // is if you're writing code which mutates a TArray which may or may not be // infallible. // // Code which merely reads from a TArray which may or may not be infallible can // simply cast the TArray to |const nsTArray&|; both fallible and infallible // TArrays can be cast to |const nsTArray&|. // template<class E, class Alloc> -class nsTArray_Impl : public nsTArray_base<Alloc, nsTArray_CopyElements<E> >, +class nsTArray_Impl : public nsTArray_base<Alloc, typename nsTArray_CopyChooser<E>::Type>, public nsTArray_TypedBase<E, nsTArray_Impl<E, Alloc> > { public: - typedef nsTArray_CopyElements<E> copy_type; + typedef typename nsTArray_CopyChooser<E>::Type copy_type; typedef nsTArray_base<Alloc, copy_type> base_type; typedef typename base_type::size_type size_type; typedef typename base_type::index_type index_type; typedef E elem_type; typedef nsTArray_Impl<E, Alloc> self_type; typedef nsTArrayElementTraits<E> elem_traits; typedef nsTArray_SafeElementAtHelper<E, self_type> safeelementat_helper_type;
--- a/xpfe/appshell/src/nsAppShellService.cpp +++ b/xpfe/appshell/src/nsAppShellService.cpp @@ -18,17 +18,19 @@ #include "nsPIWindowWatcher.h" #include "nsIDOMWindow.h" #include "nsPIDOMWindow.h" #include "nsWebShellWindow.h" #include "nsCRT.h" #include "prprf.h" +#include "nsWidgetInitData.h" #include "nsWidgetsCID.h" +#include "nsIWidget.h" #include "nsIRequestObserver.h" /* For implementing GetHiddenWindowAndJSContext */ #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "jsapi.h" #include "nsAppShellService.h"
--- a/xpfe/appshell/src/nsChromeTreeOwner.cpp +++ b/xpfe/appshell/src/nsChromeTreeOwner.cpp @@ -14,16 +14,17 @@ #include "nsIServiceManager.h" #include "nsIDocShellTreeItem.h" // Interfaces needed to include #include "nsIPrompt.h" #include "nsIAuthPrompt.h" #include "nsIBrowserDOMWindow.h" #include "nsIWebProgress.h" +#include "nsIWidget.h" #include "nsIWindowMediator.h" #include "nsIDOMChromeWindow.h" #include "nsIDOMNode.h" #include "nsIDOMElement.h" #include "nsIDOMNodeList.h" #include "nsIDOMXULElement.h" #include "nsIXULBrowserWindow.h" #include "mozilla/dom/Element.h"
--- a/xpfe/appshell/src/nsContentTreeOwner.cpp +++ b/xpfe/appshell/src/nsContentTreeOwner.cpp @@ -29,16 +29,17 @@ #include "nsIXULBrowserWindow.h" #include "nsIPrincipal.h" #include "nsIURIFixup.h" #include "nsCDefaultURIFixup.h" #include "nsIWebNavigation.h" #include "nsDocShellCID.h" #include "nsIExternalURLHandlerService.h" #include "nsIMIMEInfo.h" +#include "nsIWidget.h" #include "mozilla/BrowserElementParent.h" #include "nsIDOMDocument.h" #include "nsIScriptObjectPrincipal.h" #include "nsIURI.h" #include "nsIDocument.h" #if defined(XP_MACOSX) #include "nsThreadUtils.h"
--- a/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/xpfe/appshell/src/nsWebShellWindow.cpp @@ -21,16 +21,17 @@ #include "nsEscape.h" #include "nsPIDOMWindow.h" #include "nsIWebNavigation.h" #include "nsIWindowWatcher.h" #include "nsIDOMXULElement.h" +#include "nsWidgetInitData.h" #include "nsWidgetsCID.h" #include "nsIWidget.h" #include "nsIWidgetListener.h" #include "nsIDOMCharacterData.h" #include "nsIDOMNodeList.h" #include "nsITimer.h"
--- a/xpfe/appshell/src/nsWebShellWindow.h +++ b/xpfe/appshell/src/nsWebShellWindow.h @@ -11,16 +11,18 @@ #include "nsITimer.h" #include "nsCOMPtr.h" #include "nsXULWindow.h" #include "nsIWidgetListener.h" /* Forward declarations.... */ class nsIURI; +struct nsWidgetInitData; + namespace mozilla { class WebShellWindowTimerCallback; } // namespace mozilla class nsWebShellWindow : public nsXULWindow, public nsIWebProgressListener, public nsIWidgetListener {
--- a/xpfe/appshell/src/nsXULWindow.h +++ b/xpfe/appshell/src/nsXULWindow.h @@ -12,16 +12,17 @@ #include "nsContentTreeOwner.h" // Helper classes #include "nsCOMPtr.h" #include "nsTArray.h" #include "nsString.h" #include "nsWeakReference.h" #include "nsCOMArray.h" +#include "nsRect.h" // Interfaces needed #include "nsIBaseWindow.h" #include "nsIDocShell.h" #include "nsIDocShellTreeItem.h" #include "nsIDOMWindow.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h"