author | Ryan VanderMeulen <ryanvm@gmail.com> |
Sat, 01 Dec 2012 10:27:23 -0500 | |
changeset 114697 | ecdf0e332f170ccbcc5170766b3c754587ea08da |
parent 114577 | 0e6c4d6047db350f1720581699a1e576a9cd191d (current diff) |
parent 114696 | 1aea4afb63d91c1b2122e24a1805cbb5f0c98ce9 (diff) |
child 114699 | 1cdee6935ae2257a3c65699636955cbec003e5ea |
push id | 23926 |
push user | ryanvm@gmail.com |
push date | Sat, 01 Dec 2012 15:27:30 +0000 |
treeherder | mozilla-central@ecdf0e332f17 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 20.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
|
new file mode 100644 --- /dev/null +++ b/CLOBBER @@ -0,0 +1,18 @@ +# To Trigger a clobber replace ALL of the textual description below, +# giving a bug number and a one line description of why a clobber is +# required. Modifying this file will make configure check that a +# clobber has been performed before the build can continue. +# +# MERGE NOTE: When merging two branches that require a CLOBBER, you should +# merge both CLOBBER descriptions, to ensure that users on +# both branches correctly see the clobber warning. +# +# O <-- Users coming from both parents need to Clobber +# / \ +# O O +# | | +# O <-- Clobber O <-- Clobber +# +# Note: The description below will be part of the error message shown to users. +# +Bug 816576 - libsoundtouch is now part of libxul and not a separate dynamic library.
--- a/accessible/public/ia2/Makefile.in +++ b/accessible/public/ia2/Makefile.in @@ -67,23 +67,17 @@ MIDL_GENERATED_FILES = \ $(MIDL_INTERFACES:%.idl=%.h) \ $(MIDL_ENUMS:%.idl=%.h) \ $(NULL) EMBED_MANIFEST_AT = 2 include $(topsrcdir)/config/rules.mk -OS_LIBS = \ - kernel32.lib \ - rpcns4.lib \ - rpcrt4.lib \ - ole32.lib \ - oleaut32.lib \ - $(NULL) +OS_LIBS = $(call EXPAND_LIBNAME,uuid kernel32 rpcns4 rpcrt4 ole32 oleaut32) # generate list of to-be-generated files that are missing # but ignore special file dlldata.c missing:=$(strip $(foreach onefile,$(strip $(subst dlldata.c,,$(MIDL_GENERATED_FILES))),$(if $(wildcard $(onefile)),,$(onefile)))) missing_base:=$(sort $(basename $(subst _p.c,,$(subst _i.c,,$(missing))))) $(MIDL_GENERATED_FILES) : midl_done
--- a/accessible/public/msaa/Makefile.in +++ b/accessible/public/msaa/Makefile.in @@ -46,22 +46,17 @@ MIDL_GENERATED_FILES = \ ISimpleDOMDocument_i.c \ ISimpleDOMText.h \ ISimpleDOMText_p.c \ ISimpleDOMText_i.c \ $(NULL) SRCDIR_CSRCS = $(addprefix $(srcdir)/,$(CSRCS)) -OS_LIBS = \ - kernel32.lib \ - rpcns4.lib \ - rpcrt4.lib \ - oleaut32.lib \ - $(NULL) +OS_LIBS = $(call EXPAND_LIBNAME,kernel32 rpcns4 rpcrt4 oleaut32) $(MIDL_GENERATED_FILES): done_gen done_gen: ISimpleDOMNode.idl \ ISimpleDOMDocument.idl \ ISimpleDOMText.idl $(MIDL) $(MIDL_FLAGS) -I $(srcdir) -Oicf $(srcdir)/ISimpleDOMNode.idl
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp +++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp @@ -524,48 +524,58 @@ ApplicationAccessibleWrap::ApplicationAc if (ShouldA11yBeEnabled()) { // Load and initialize gail library. nsresult rv = LoadGtkModule(sGail); if (NS_SUCCEEDED(rv)) { (*sGail.init)(); } else { MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName)); } - - MAI_LOG_DEBUG(("Mozilla Atk Implementation initializing\n")); - - // Initialize the MAI Utility class, it will overwrite gail_util. - g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL)); - - // Init atk-bridge now - PR_SetEnv("NO_AT_BRIDGE=0"); + } +} - // load and initialize atk-bridge library - rv = LoadGtkModule(sAtkBridge); - if (NS_SUCCEEDED(rv)) { - (*sAtkBridge.init)(); - } else { - MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName)); - } +// XXX we can't do this in ApplicationAccessibleWrap's constructor because +// a11y::ApplicationAcc() will return null then which breaks atk's attempt to +// get the application's root accessible during initialization. this needs to +// be defined here because LoadGtkModule() and the library info is static. See +// bug 817133. +void +nsAccessNodeWrap::InitAccessibility() +{ + if (!ShouldA11yBeEnabled()) + return; - if (!sToplevel_event_hook_added) { - sToplevel_event_hook_added = true; - sToplevel_show_hook = - g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW), - 0, toplevel_event_watcher, - reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW), NULL); - sToplevel_hide_hook = - g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), - 0, toplevel_event_watcher, - reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_HIDE), NULL); - } + // Initialize the MAI Utility class, it will overwrite gail_util. + g_type_class_unref(g_type_class_ref(MAI_TYPE_UTIL)); + + // Init atk-bridge now + PR_SetEnv("NO_AT_BRIDGE=0"); + nsresult rv = LoadGtkModule(sAtkBridge); + if (NS_SUCCEEDED(rv)) { + (*sAtkBridge.init)(); + } else { + MAI_LOG_DEBUG(("Fail to load lib: %s\n", sAtkBridge.libName)); } + if (!sToplevel_event_hook_added) { + sToplevel_event_hook_added = true; + sToplevel_show_hook = + g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW), + 0, toplevel_event_watcher, + reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW), + NULL); + sToplevel_hide_hook = + g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), 0, + toplevel_event_watcher, + reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_HIDE), + NULL); + } } + ApplicationAccessibleWrap::~ApplicationAccessibleWrap() { MAI_LOG_DEBUG(("======Destory AppRootAcc=%p\n", (void*)this)); AccessibleWrap::ShutdownAtkObject(); } static gboolean toplevel_event_watcher(GSignalInvocationHint* ihint,
--- a/accessible/src/atk/nsAccessNodeWrap.cpp +++ b/accessible/src/atk/nsAccessNodeWrap.cpp @@ -28,16 +28,12 @@ nsAccessNodeWrap:: //----------------------------------------------------- // destruction //----------------------------------------------------- nsAccessNodeWrap::~nsAccessNodeWrap() { } -void nsAccessNodeWrap::InitAccessibility() -{ -} - void nsAccessNodeWrap::ShutdownAccessibility() { }
--- a/accessible/src/base/TreeWalker.cpp +++ b/accessible/src/base/TreeWalker.cpp @@ -82,17 +82,18 @@ TreeWalker::NextChildInternal(bool aNoWa mState->childList->GetLength(&length); while (mState->childIdx < length) { nsIContent* childNode = mState->childList->Item(mState->childIdx); mState->childIdx++; bool isSubtreeHidden = false; Accessible* accessible = mWalkCache ? mDoc->GetAccessible(childNode) : - GetAccService()->GetOrCreateAccessible(childNode, mDoc, &isSubtreeHidden); + GetAccService()->GetOrCreateAccessible(childNode, mContext, + &isSubtreeHidden); if (accessible) return accessible; // Walk down into subtree to find accessibles. if (!isSubtreeHidden) { if (!PushState(childNode)) break;
--- a/accessible/src/base/nsARIAMap.cpp +++ b/accessible/src/base/nsARIAMap.cpp @@ -105,17 +105,17 @@ static nsRoleMapEntry sWAIRoleMaps[] = }, { // columnheader &nsGkAtoms::columnheader, roles::COLUMNHEADER, kUseMapRole, eNoValue, eSortAction, eNoLiveAttr, - kGenericAccType, + Accessible::eTableCellAccessible, kNoReqStates, eARIASelectable, eARIAReadonly }, { // combobox &nsGkAtoms::combobox, roles::COMBOBOX, kUseMapRole, @@ -170,29 +170,29 @@ static nsRoleMapEntry sWAIRoleMaps[] = }, { // grid &nsGkAtoms::grid, roles::TABLE, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, - Accessible::eSelectAccessible, + Accessible::eSelectAccessible | Accessible::eTableAccessible, states::FOCUSABLE, eARIAMultiSelectable, eARIAReadonly }, { // gridcell &nsGkAtoms::gridcell, roles::GRID_CELL, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, - kGenericAccType, + Accessible::eTableCellAccessible, kNoReqStates, eARIASelectable, eARIAReadonly }, { // group &nsGkAtoms::group, roles::GROUPING, kUseMapRole, @@ -424,17 +424,17 @@ static nsRoleMapEntry sWAIRoleMaps[] = }, { // row &nsGkAtoms::row, roles::ROW, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, - kGenericAccType, + Accessible::eTableRowAccessible, kNoReqStates, eARIASelectable }, { // rowgroup &nsGkAtoms::rowgroup, roles::GROUPING, kUseMapRole, eNoValue, @@ -445,17 +445,17 @@ static nsRoleMapEntry sWAIRoleMaps[] = }, { // rowheader &nsGkAtoms::rowheader, roles::ROWHEADER, kUseMapRole, eNoValue, eSortAction, eNoLiveAttr, - kGenericAccType, + Accessible::eTableCellAccessible, kNoReqStates, eARIASelectable, eARIAReadonly }, { // scrollbar &nsGkAtoms::scrollbar, roles::SCROLLBAR, kUseMapRole, @@ -598,17 +598,17 @@ static nsRoleMapEntry sWAIRoleMaps[] = }, { // treegrid &nsGkAtoms::treegrid, roles::TREE_TABLE, kUseMapRole, eNoValue, eNoAction, eNoLiveAttr, - Accessible::eSelectAccessible, + Accessible::eSelectAccessible | Accessible::eTableAccessible, kNoReqStates, eARIAReadonly, eARIAMultiSelectable }, { // treeitem &nsGkAtoms::treeitem, roles::OUTLINEITEM, kUseMapRole,
--- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -203,79 +203,59 @@ nsAccessibilityService::GetRootDocumentA } } return nullptr; } already_AddRefed<Accessible> nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc) + Accessible* aContext) { - // We can have several cases here: - // 1) a text or html embedded document where the contentDocument variable in - // the object element holds the content; - // 2) web content that uses a plugin, which means we will have to go to - // the plugin to get the accessible content; - // 3) an image or imagemap, where the image frame points back to the object - // element DOMNode. - + // nsObjectFrame means a plugin, so we need to use the accessibility support + // of the plugin. if (aFrame->GetRect().IsEmpty()) return nullptr; - // 1) for object elements containing either HTML or TXT documents - nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(aContent)); - if (obj) { - nsCOMPtr<nsIDOMDocument> domDoc; - obj->GetContentDocument(getter_AddRefs(domDoc)); - if (domDoc) { - Accessible* newAcc = new OuterDocAccessible(aContent, aDoc); - NS_ADDREF(newAcc); - return newAcc; - } - } - #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK) - // 2) for plugins nsRefPtr<nsNPAPIPluginInstance> pluginInstance; if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) && pluginInstance) { #ifdef XP_WIN // Note: pluginPort will be null if windowless. HWND pluginPort = nullptr; aFrame->GetPluginPort(&pluginPort); Accessible* accessible = - new HTMLWin32ObjectOwnerAccessible(aContent, aDoc, pluginPort); + new HTMLWin32ObjectOwnerAccessible(aContent, aContext->Document(), + pluginPort); NS_ADDREF(accessible); return accessible; #elif MOZ_ACCESSIBILITY_ATK if (!AtkSocketAccessible::gCanEmbed) return nullptr; + // Note this calls into the plugin, so crazy things may happen and aFrame + // may go away. nsCString plugId; nsresult rv = pluginInstance->GetValueFromPlugin( NPPVpluginNativeAccessibleAtkPlugId, &plugId); if (NS_SUCCEEDED(rv) && !plugId.IsEmpty()) { AtkSocketAccessible* socketAccessible = - new AtkSocketAccessible(aContent, aDoc, plugId); + new AtkSocketAccessible(aContent, aContext->Document(), plugId); NS_ADDREF(socketAccessible); return socketAccessible; } #endif } #endif - // 3) for images and imagemaps, or anything else with a child frame - // we have the object frame, get the image frame - nsIFrame* childFrame = aFrame->GetFirstPrincipalChild(); - return childFrame ? CreateAccessibleByFrameType(childFrame, aContent, aDoc) : - nullptr; + return nullptr; } void nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell, nsIContent* aContainer, nsIContent* aStartChild, nsIContent* aEndChild) { @@ -673,27 +653,31 @@ nsAccessibilityService::IsLogged(const n return NS_OK; } //////////////////////////////////////////////////////////////////////////////// // nsAccessibilityService public Accessible* nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, - DocAccessible* aDoc, + Accessible* aContext, bool* aIsSubtreeHidden) { - if (!aDoc || !aNode || gIsShutdown) - return nullptr; + NS_PRECONDITION(aContext && aNode && !gIsShutdown, + "Maybe let'd do a crash? Oh, yes, baby!"); if (aIsSubtreeHidden) *aIsSubtreeHidden = false; + DocAccessible* document = aContext->Document(); + // Check to see if we already have an accessible for this node in the cache. - Accessible* cachedAccessible = aDoc->GetAccessible(aNode); + // XXX: we don't have context check here. It doesn't really necessary until + // we have in-law children adoption. + Accessible* cachedAccessible = document->GetAccessible(aNode); if (cachedAccessible) return cachedAccessible; // No cache entry, so we must create the accessible. if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) { // If it's document node then ask accessible document loader for // document accessible, otherwise return null. @@ -702,17 +686,17 @@ nsAccessibilityService::GetOrCreateAcces } // We have a content node. if (!aNode->IsInDoc()) { NS_WARNING("Creating accessible for node with no document"); return nullptr; } - if (aNode->OwnerDoc() != aDoc->DocumentNode()) { + if (aNode->OwnerDoc() != document->DocumentNode()) { NS_ERROR("Creating accessible for wrong document"); return nullptr; } if (!aNode->IsContent()) return nullptr; nsIContent* content = aNode->AsContent(); @@ -758,18 +742,18 @@ nsAccessibilityService::GetOrCreateAcces frame->GetRenderedText(&text, nullptr, nullptr, 0, UINT32_MAX); if (text.IsEmpty()) { if (aIsSubtreeHidden) *aIsSubtreeHidden = true; return nullptr; } - newAcc = CreateAccessibleByFrameType(frame, content, aDoc); - if (aDoc->BindToDocument(newAcc, nullptr)) { + newAcc = CreateAccessibleByFrameType(frame, content, aContext); + if (document->BindToDocument(newAcc, nullptr)) { newAcc->AsTextLeaf()->SetText(text); return newAcc; } return nullptr; } bool isHTML = content->IsHTML(); @@ -785,175 +769,119 @@ nsAccessibilityService::GetOrCreateAcces if (nsLayoutUtils::GetAllInFlowRectsUnion(frame, frame->GetParent()).IsEmpty()) { if (aIsSubtreeHidden) *aIsSubtreeHidden = true; return nullptr; } - newAcc = new HyperTextAccessibleWrap(content, aDoc); - if (aDoc->BindToDocument(newAcc, aria::GetRoleMap(aNode))) + newAcc = new HyperTextAccessibleWrap(content, document); + if (document->BindToDocument(newAcc, aria::GetRoleMap(aNode))) return newAcc; return nullptr; } nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aNode); // If the element is focusable or global ARIA attribute is applied to it or // it is referenced by ARIA relationship then treat role="presentation" on // the element as the role is not there. if (roleMapEntry && roleMapEntry->Is(nsGkAtoms::presentation)) { - if (!MustBeAccessible(content, aDoc)) + if (!MustBeAccessible(content, document)) return nullptr; roleMapEntry = nullptr; } if (!newAcc && isHTML) { // HTML accessibles - nsIAtom* frameType = frame->GetType(); - - bool partOfHTMLTable = - frameType == nsGkAtoms::tableCaptionFrame || - frameType == nsGkAtoms::tableCellFrame || - frameType == nsGkAtoms::tableRowGroupFrame || - frameType == nsGkAtoms::tableRowFrame; - bool legalPartOfHTMLTable = partOfHTMLTable; - - if (partOfHTMLTable) { - // Table-related frames don't get table-related roles - // unless they are inside a table, but they may still get generic - // accessibles - nsIContent *tableContent = content; - while ((tableContent = tableContent->GetParent()) != nullptr) { - nsIFrame *tableFrame = tableContent->GetPrimaryFrame(); - if (!tableFrame) - continue; - - if (tableFrame->GetType() == nsGkAtoms::tableOuterFrame) { - Accessible* tableAccessible = aDoc->GetAccessible(tableContent); - - if (tableAccessible) { - if (!roleMapEntry) { - roles::Role role = tableAccessible->Role(); - // No ARIA role and not in table: override role. For example, - // <table role="label"><td>content</td></table> - if (role != roles::TABLE && role != roles::TREE_TABLE) - roleMapEntry = &nsARIAMap::gEmptyRoleMap; - } - - break; - } - -#ifdef DEBUG - nsRoleMapEntry* tableRoleMapEntry = aria::GetRoleMap(tableContent); - NS_ASSERTION(tableRoleMapEntry && tableRoleMapEntry->Is(nsGkAtoms::presentation), - "No accessible for parent table and it didn't have role of presentation"); -#endif - - if (!roleMapEntry && !MustBeAccessible(content, aDoc)) { - // Table-related descendants of presentation table are also - // presentation if they aren't focusable and have not explicit ARIA - // role (don't create accessibles for them unless they need to fire - // focus events). - return nullptr; - } - - // otherwise create ARIA based accessible. - legalPartOfHTMLTable = false; - break; + if (roleMapEntry) { + // Create pure ARIA grid/treegrid related accessibles if they weren't used + // on accessible HTML table elements. + if ((roleMapEntry->accTypes & Accessible::eTableCellAccessible)) { + if (aContext->IsOfType(Accessible::eTableRowAccessible) && + (frame->AccessibleType() != eHTMLTableCellAccessible || + aContext->GetContent() != content->GetParent())) { + newAcc = new ARIAGridCellAccessibleWrap(content, document); } - if (tableContent->Tag() == nsGkAtoms::table) { - // Stop before we are fooled by any additional table ancestors - // This table cell frameis part of a separate ancestor table. - legalPartOfHTMLTable = false; - break; - } - } - - if (!tableContent) - legalPartOfHTMLTable = false; - } - - if (roleMapEntry) { - // Create ARIA grid/treegrid accessibles if node is not a child or legal - // child of HTML table and is not a HTML table. - if ((!partOfHTMLTable || !legalPartOfHTMLTable) && - frameType != nsGkAtoms::tableOuterFrame) { - - if (roleMapEntry->role == roles::TABLE || - roleMapEntry->role == roles::TREE_TABLE) { - newAcc = new ARIAGridAccessibleWrap(content, aDoc); - - } else if (roleMapEntry->role == roles::GRID_CELL || - roleMapEntry->role == roles::ROWHEADER || - roleMapEntry->role == roles::COLUMNHEADER) { - newAcc = new ARIAGridCellAccessibleWrap(content, aDoc); - } + } else if ((roleMapEntry->accTypes & Accessible::eTableAccessible) && + frame->AccessibleType() != eHTMLTableAccessible) { + newAcc = new ARIAGridAccessibleWrap(content, document); } } if (!newAcc) { - // Prefer to use markup (mostly tag name, perhaps attributes) to - // decide if and what kind of accessible to create. - // The method creates accessibles for table related content too therefore - // we do not call it if accessibles for table related content are - // prevented above. - newAcc = CreateHTMLAccessibleByMarkup(frame, content, aDoc, - legalPartOfHTMLTable); + // Prefer to use markup (mostly tag name, perhaps attributes) to decide if + // and what kind of accessible to create. + newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext); // Try using frame to do it. - if (!newAcc && (!partOfHTMLTable || legalPartOfHTMLTable)) - newAcc = CreateAccessibleByFrameType(frame, content, aDoc); + if (!newAcc) + newAcc = CreateAccessibleByFrameType(frame, content, aContext); + + // If table has strong ARIA role then all table descendants shouldn't + // expose their native roles. + if (!roleMapEntry && newAcc) { + if (frame->AccessibleType() == eHTMLTableRowAccessible) { + nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); + if (contextRoleMap && + !(contextRoleMap->accTypes & Accessible::eTableAccessible)) + roleMapEntry = &nsARIAMap::gEmptyRoleMap; + + } else if (frame->AccessibleType() == eHTMLTableCellAccessible && + aContext->ARIARoleMap() == &nsARIAMap::gEmptyRoleMap) { + roleMapEntry = &nsARIAMap::gEmptyRoleMap; + } + } } } if (!newAcc) { // Elements may implement nsIAccessibleProvider via XBL. This allows them to // say what kind of accessible to create. - newAcc = CreateAccessibleByType(content, aDoc); + newAcc = CreateAccessibleByType(content, document); } if (!newAcc) { // xul:deck does not have XBL and nsIFrame::CreateAccessible() is only called // on HTML elements nsIAtom* tag = content->Tag(); if ((tag == nsGkAtoms::deck) || (tag == nsGkAtoms::tabpanels)) { - newAcc = new XULDeckAccessible(content, aDoc); + newAcc = new XULDeckAccessible(content, document); } else if (content->IsSVG(nsGkAtoms::svg)) { - newAcc = new EnumRoleAccessible(content, aDoc, roles::DIAGRAM); + newAcc = new EnumRoleAccessible(content, document, roles::DIAGRAM); } else if (content->IsMathML(nsGkAtoms::math)) { - newAcc = new EnumRoleAccessible(content, aDoc, roles::EQUATION); + newAcc = new EnumRoleAccessible(content, document, roles::EQUATION); } } if (!newAcc) - newAcc = CreateAccessibleForDeckChild(frame, content, aDoc); + newAcc = CreateAccessibleForDeckChild(frame, content, document); // If no accessible, see if we need to create a generic accessible because // of some property that makes this object interesting // We don't do this for <body>, <html>, <window>, <dialog> etc. which // correspond to the doc accessible and will be created in any case if (!newAcc && content->Tag() != nsGkAtoms::body && content->GetParent() && - (roleMapEntry || MustBeAccessible(content, aDoc) || + (roleMapEntry || MustBeAccessible(content, document) || (isHTML && nsCoreUtils::HasClickListener(content)))) { // This content is focusable or has an interesting dynamic content accessibility property. // If it's interesting we need it in the accessibility hierarchy so that events or // other accessibles can point to it, or so that it can hold a state, etc. if (isHTML) { // Interesting HTML container which may have selectable text and/or embedded objects - newAcc = new HyperTextAccessibleWrap(content, aDoc); + newAcc = new HyperTextAccessibleWrap(content, document); } else { // XUL, SVG, MathML etc. // Interesting generic non-HTML container - newAcc = new AccessibleWrap(content, aDoc); + newAcc = new AccessibleWrap(content, document); } } - return aDoc->BindToDocument(newAcc, roleMapEntry) ? newAcc : nullptr; + return document->BindToDocument(newAcc, roleMapEntry) ? newAcc : nullptr; } //////////////////////////////////////////////////////////////////////////////// // nsAccessibilityService private bool nsAccessibilityService::Init() { @@ -1233,209 +1161,234 @@ nsAccessibilityService::CreateAccessible NS_IF_ADDREF(accessible); return accessible; } already_AddRefed<Accessible> nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc, - bool aIsLegalPartOfHTMLTable) + Accessible* aContext) { - if (aIsLegalPartOfHTMLTable) { - if (nsCoreUtils::IsHTMLTableHeader(aContent)) { - Accessible* accessible = - new HTMLTableHeaderCellAccessibleWrap(aContent, aDoc); + DocAccessible* document = aContext->Document(); + if (aContext->IsOfType(Accessible::eTableRowAccessible)) { + if (nsCoreUtils::IsHTMLTableHeader(aContent) && + aContext->GetContent() == aContent->GetParent()) { + Accessible* accessible = new HTMLTableHeaderCellAccessibleWrap(aContent, + document); NS_ADDREF(accessible); return accessible; } return nullptr; } // This method assumes we're in an HTML namespace. nsIAtom* tag = aContent->Tag(); if (tag == nsGkAtoms::figcaption) { - Accessible* accessible = new HTMLFigcaptionAccessible(aContent, aDoc); + Accessible* accessible = new HTMLFigcaptionAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::figure) { - Accessible* accessible = new HTMLFigureAccessible(aContent, aDoc); + Accessible* accessible = new HTMLFigureAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::legend) { - Accessible* accessible = new HTMLLegendAccessible(aContent, aDoc); + Accessible* accessible = new HTMLLegendAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::option) { - Accessible* accessible = new HTMLSelectOptionAccessible(aContent, aDoc); + Accessible* accessible = new HTMLSelectOptionAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::optgroup) { - Accessible* accessible = new HTMLSelectOptGroupAccessible(aContent, aDoc); + Accessible* accessible = + new HTMLSelectOptGroupAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::ul || tag == nsGkAtoms::ol || tag == nsGkAtoms::dl) { - Accessible* accessible = new HTMLListAccessible(aContent, aDoc); + Accessible* accessible = new HTMLListAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::a) { // Only some roles truly enjoy life as HTMLLinkAccessibles, for details // see closed bug 494807. nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent); if (roleMapEntry && roleMapEntry->role != roles::NOTHING && roleMapEntry->role != roles::LINK) { - Accessible* accessible = new HyperTextAccessibleWrap(aContent, aDoc); + Accessible* accessible = new HyperTextAccessibleWrap(aContent, document); NS_ADDREF(accessible); return accessible; } - Accessible* accessible = new HTMLLinkAccessible(aContent, aDoc); + Accessible* accessible = new HTMLLinkAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::dt || tag == nsGkAtoms::li) { // Create list item accessible unconditionally by tag name. nsBlockFrame // creates the list item accessible for other elements styled as list items. - Accessible* accessible = new HTMLLIAccessible(aContent, aDoc); + Accessible* accessible = new HTMLLIAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::abbr || tag == nsGkAtoms::acronym || tag == nsGkAtoms::blockquote || tag == nsGkAtoms::dd || tag == nsGkAtoms::form || tag == nsGkAtoms::h1 || tag == nsGkAtoms::h2 || tag == nsGkAtoms::h3 || tag == nsGkAtoms::h4 || tag == nsGkAtoms::h5 || tag == nsGkAtoms::h6 || tag == nsGkAtoms::q) { - Accessible* accessible = new HyperTextAccessibleWrap(aContent, aDoc); + Accessible* accessible = new HyperTextAccessibleWrap(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::output) { - Accessible* accessible = new HTMLOutputAccessible(aContent, aDoc); + Accessible* accessible = new HTMLOutputAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } if (tag == nsGkAtoms::progress) { Accessible* accessible = - new HTMLProgressMeterAccessible(aContent, aDoc); + new HTMLProgressMeterAccessible(aContent, document); NS_ADDREF(accessible); return accessible; } return nullptr; } already_AddRefed<Accessible> nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc) + Accessible* aContext) { + DocAccessible* document = aContext->Document(); + nsRefPtr<Accessible> newAcc; switch (aFrame->AccessibleType()) { case eNoAccessible: return nullptr; case eHTMLBRAccessible: - newAcc = new HTMLBRAccessible(aContent, aDoc); + newAcc = new HTMLBRAccessible(aContent, document); break; case eHTMLButtonAccessible: - newAcc = new HTMLButtonAccessible(aContent, aDoc); + newAcc = new HTMLButtonAccessible(aContent, document); break; case eHTMLCanvasAccessible: - newAcc = new HTMLCanvasAccessible(aContent, aDoc); + newAcc = new HTMLCanvasAccessible(aContent, document); break; case eHTMLCaptionAccessible: - newAcc = new HTMLCaptionAccessible(aContent, aDoc); + if (aContext->IsOfType(Accessible::eTableAccessible) && + aContext->GetContent() == aContent->GetParent()) { + newAcc = new HTMLCaptionAccessible(aContent, document); + } break; case eHTMLCheckboxAccessible: - newAcc = new HTMLCheckboxAccessible(aContent, aDoc); + newAcc = new HTMLCheckboxAccessible(aContent, document); break; case eHTMLComboboxAccessible: - newAcc = new HTMLComboboxAccessible(aContent, aDoc); + newAcc = new HTMLComboboxAccessible(aContent, document); break; case eHTMLFileInputAccessible: - newAcc = new HTMLFileInputAccessible(aContent, aDoc); + newAcc = new HTMLFileInputAccessible(aContent, document); break; case eHTMLGroupboxAccessible: - newAcc = new HTMLGroupboxAccessible(aContent, aDoc); + newAcc = new HTMLGroupboxAccessible(aContent, document); break; case eHTMLHRAccessible: - newAcc = new HTMLHRAccessible(aContent, aDoc); + newAcc = new HTMLHRAccessible(aContent, document); break; case eHTMLImageMapAccessible: - newAcc = new HTMLImageMapAccessible(aContent, aDoc); + newAcc = new HTMLImageMapAccessible(aContent, document); break; case eHTMLLabelAccessible: - newAcc = new HTMLLabelAccessible(aContent, aDoc); + newAcc = new HTMLLabelAccessible(aContent, document); break; case eHTMLLiAccessible: - newAcc = new HTMLLIAccessible(aContent, aDoc); + newAcc = new HTMLLIAccessible(aContent, document); break; case eHTMLSelectListAccessible: - newAcc = new HTMLSelectListAccessible(aContent, aDoc); + newAcc = new HTMLSelectListAccessible(aContent, document); break; case eHTMLMediaAccessible: - newAcc = new EnumRoleAccessible(aContent, aDoc, roles::GROUPING); + newAcc = new EnumRoleAccessible(aContent, document, roles::GROUPING); break; case eHTMLObjectFrameAccessible: { nsObjectFrame* objectFrame = do_QueryFrame(aFrame); - newAcc = CreateHTMLObjectFrameAccessible(objectFrame, aContent, aDoc); + newAcc = CreateHTMLObjectFrameAccessible(objectFrame, aContent, aContext); break; } case eHTMLRadioButtonAccessible: - newAcc = new HTMLRadioButtonAccessible(aContent, aDoc); + newAcc = new HTMLRadioButtonAccessible(aContent, document); break; case eHTMLTableAccessible: - newAcc = new HTMLTableAccessibleWrap(aContent, aDoc); + newAcc = new HTMLTableAccessibleWrap(aContent, document); break; case eHTMLTableCellAccessible: - newAcc = new HTMLTableCellAccessibleWrap(aContent, aDoc); + // Accessible HTML table cell must be a child of accessible HTML table row. + if (aContext->IsOfType(Accessible::eHTMLTableRowAccessible)) + newAcc = new HTMLTableCellAccessibleWrap(aContent, document); break; - case eHTMLTableRowAccessible: - newAcc = new EnumRoleAccessible(aContent, aDoc, roles::ROW); + + case eHTMLTableRowAccessible: { + // Accessible HTML table row must be a child of tbody/tfoot/thead of + // accessible HTML table or must be a child of accessible of HTML table. + if (aContext->IsOfType(Accessible::eTableAccessible)) { + nsIContent* parentContent = aContent->GetParent(); + nsIFrame* parentFrame = parentContent->GetPrimaryFrame(); + if (parentFrame->GetType() == nsGkAtoms::tableRowGroupFrame) { + parentContent = parentContent->GetParent(); + parentFrame = parentContent->GetPrimaryFrame(); + } + + if (parentFrame->GetType() == nsGkAtoms::tableOuterFrame && + aContext->GetContent() == parentContent) { + newAcc = new HTMLTableRowAccessible(aContent, document); + } + } break; + } case eHTMLTextFieldAccessible: - newAcc = new HTMLTextFieldAccessible(aContent, aDoc); + newAcc = new HTMLTextFieldAccessible(aContent, document); break; case eHyperTextAccessible: - newAcc = new HyperTextAccessibleWrap(aContent, aDoc); + newAcc = new HyperTextAccessibleWrap(aContent, document); break; case eImageAccessible: - newAcc = new ImageAccessibleWrap(aContent, aDoc); + newAcc = new ImageAccessibleWrap(aContent, document); break; case eOuterDocAccessible: - newAcc = new OuterDocAccessible(aContent, aDoc); + newAcc = new OuterDocAccessible(aContent, document); break; case eTextLeafAccessible: - newAcc = new TextLeafAccessibleWrap(aContent, aDoc); + newAcc = new TextLeafAccessibleWrap(aContent, document); break; } return newAcc.forget(); } //////////////////////////////////////////////////////////////////////////////// // nsIAccessibilityService (DON'T put methods here)
--- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -78,17 +78,17 @@ public: NS_DECL_NSIACCESSIBLERETRIEVAL NS_DECL_NSIOBSERVER // nsIAccessibilityService virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell, bool aCanCreate); already_AddRefed<Accessible> CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc); + Accessible* aContext); /** * Adds/remove ATK root accessible for gtk+ native window to/from children * of the application accessible. */ virtual Accessible* AddNativeRootAccessible(void* aAtkAccessible); virtual void RemoveNativeRootAccessible(Accessible* aRootAccessible); @@ -150,21 +150,21 @@ public: */ static bool IsShutdown() { return gIsShutdown; } /** * Return an accessible for the given DOM node from the cache or create new * one. * * @param aNode [in] the given node - * @param aDoc [in] the doc accessible of the node + * @param aContext [in] context the accessible is created in * @param aIsSubtreeHidden [out, optional] indicates whether the node's * frame and its subtree is hidden */ - Accessible* GetOrCreateAccessible(nsINode* aNode, DocAccessible* aDoc, + Accessible* GetOrCreateAccessible(nsINode* aNode, Accessible* aContext, bool* aIsSubtreeHidden = nullptr); private: // nsAccessibilityService creation is controlled by friend // NS_GetAccessibilityService, keep constructors private. nsAccessibilityService(); nsAccessibilityService(const nsAccessibilityService&); nsAccessibilityService& operator =(const nsAccessibilityService&); @@ -187,25 +187,24 @@ private: already_AddRefed<Accessible> CreateAccessibleByType(nsIContent* aContent, DocAccessible* aDoc); /** * Create accessible for HTML node by tag name. */ already_AddRefed<Accessible> CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc, - bool aIsLegalPartOfHTMLTable); + Accessible* aContext); /** * Create an accessible whose type depends on the given frame. */ already_AddRefed<Accessible> CreateAccessibleByFrameType(nsIFrame* aFrame, nsIContent* aContent, - DocAccessible* aDoc); + Accessible* aContext); /** * Create accessible if parent is a deck frame. */ already_AddRefed<Accessible> CreateAccessibleForDeckChild(nsIFrame* aFrame, nsIContent* aContent, DocAccessible* aDoc);
--- a/accessible/src/generic/Accessible.h +++ b/accessible/src/generic/Accessible.h @@ -167,18 +167,22 @@ public: /** * Return enumerated accessible role (see constants in Role.h). */ mozilla::a11y::role Role(); /** * Return true if ARIA role is specified on the element. */ - bool HasARIARole() const - { return mRoleMapEntry; } + bool HasARIARole() const { return mRoleMapEntry; } + + /** + * Retrun ARIA role map if any. + */ + nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; } /** * Return accessible role specified by ARIA (see constants in * roles). */ mozilla::a11y::role ARIARole(); /** @@ -688,16 +692,21 @@ public: { return HasOwnContent() && !(mFlags & eNotNodeMapEntry); } /** * Return true if the accessible has associated DOM content. */ bool HasOwnContent() const { return mContent && !(mFlags & eSharedNode); } /** + * Return true if accessible is of given type. + */ + bool IsOfType(uint32_t aType) const { return mFlags & aType; } + + /** * Return true if the accessible has a numeric value. */ bool HasNumericValue() const; protected: /** * Return the accessible name provided by native markup. It doesn't take @@ -773,27 +782,31 @@ public: // XXX: a small hack to make the eApplicationAccessible = 1 << 7, eAutoCompleteAccessible = 1 << 8, eAutoCompletePopupAccessible = 1 << 9, eComboboxAccessible = 1 << 10, eDocAccessible = 1 << 11, eHyperTextAccessible = 1 << 12, eHTMLFileInputAccessible = 1 << 13, eHTMLListItemAccessible = 1 << 14, - eImageAccessible = 1 << 15, - eImageMapAccessible = 1 << 16, - eListControlAccessible = 1 << 17, - eMenuButtonAccessible = 1 << 18, - eMenuPopupAccessible = 1 << 19, - eProgressAccessible = 1 << 20, - eRootAccessible = 1 << 21, - eSelectAccessible = 1 << 22, - eTextLeafAccessible = 1 << 23, - eXULDeckAccessible = 1 << 24, - eXULTreeAccessible = 1 << 25 + eHTMLTableRowAccessible = 1 << 15, + eImageAccessible = 1 << 16, + eImageMapAccessible = 1 << 17, + eListControlAccessible = 1 << 18, + eMenuButtonAccessible = 1 << 19, + eMenuPopupAccessible = 1 << 20, + eProgressAccessible = 1 << 21, + eRootAccessible = 1 << 22, + eSelectAccessible = 1 << 23, + eTableAccessible = 1 << 24, + eTableCellAccessible = 1 << 25, + eTableRowAccessible = 1 << 26, + eTextLeafAccessible = 1 << 27, + eXULDeckAccessible = 1 << 28, + eXULTreeAccessible = 1 << 29 }; protected: ////////////////////////////////////////////////////////////////////////////// // Miscellaneous helpers /**
--- a/accessible/src/html/HTMLSelectAccessible.cpp +++ b/accessible/src/html/HTMLSelectAccessible.cpp @@ -140,17 +140,17 @@ HTMLSelectListAccessible::CacheOptSiblin } nsIAtom* tag = childContent->Tag(); if (tag == nsGkAtoms::option || tag == nsGkAtoms::optgroup) { // Get an accessible for option or optgroup and cache it. nsRefPtr<Accessible> accessible = - GetAccService()->GetOrCreateAccessible(childContent, mDoc); + GetAccService()->GetOrCreateAccessible(childContent, this); if (accessible) AppendChild(accessible); // Deep down into optgroup element. if (tag == nsGkAtoms::optgroup) CacheOptSiblings(childContent); } }
--- a/accessible/src/html/HTMLTableAccessible.cpp +++ b/accessible/src/html/HTMLTableAccessible.cpp @@ -316,24 +316,38 @@ HTMLTableHeaderCellAccessible::NativeRol } } // No elements in siblings what means the table has one column only. Therefore // it should be column header. return roles::COLUMNHEADER; } + +//////////////////////////////////////////////////////////////////////////////// +// HTMLTableRowAccessible +//////////////////////////////////////////////////////////////////////////////// + +NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableRowAccessible, Accessible) + +role +HTMLTableRowAccessible::NativeRole() +{ + return roles::ROW; +} + //////////////////////////////////////////////////////////////////////////////// // HTMLTableAccessible //////////////////////////////////////////////////////////////////////////////// HTMLTableAccessible:: HTMLTableAccessible(nsIContent* aContent, DocAccessible* aDoc) : AccessibleWrap(aContent, aDoc), xpcAccessibleTable(this) { + mFlags |= eTableAccessible; } //////////////////////////////////////////////////////////////////////////////// // HTMLTableAccessible: nsISupports implementation NS_IMPL_ISUPPORTS_INHERITED1(HTMLTableAccessible, Accessible, nsIAccessibleTable)
--- a/accessible/src/html/HTMLTableAccessible.h +++ b/accessible/src/html/HTMLTableAccessible.h @@ -81,16 +81,34 @@ public: HTMLTableHeaderCellAccessible(nsIContent* aContent, DocAccessible* aDoc); // Accessible virtual a11y::role NativeRole(); }; /** + * HTML table row accessible (html:tr). + */ +class HTMLTableRowAccessible : public AccessibleWrap +{ +public: + HTMLTableRowAccessible(nsIContent* aContent, DocAccessible* aDoc) : + AccessibleWrap(aContent, aDoc) + { mFlags |= eTableRowAccessible | eHTMLTableRowAccessible; } + virtual ~HTMLTableRowAccessible() { } + + NS_DECL_ISUPPORTS_INHERITED + + // Accessible + virtual a11y::role NativeRole(); +}; + + +/** * HTML table accessible (html:table). */ // To turn on table debugging descriptions define SHOW_LAYOUT_HEURISTIC // This allow release trunk builds to be used by testers to refine the // data vs. layout heuristic // #define SHOW_LAYOUT_HEURISTIC
--- a/accessible/src/xul/XULTreeGridAccessible.cpp +++ b/accessible/src/xul/XULTreeGridAccessible.cpp @@ -23,16 +23,17 @@ using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // XULTreeGridAccessible //////////////////////////////////////////////////////////////////////////////// XULTreeGridAccessible:: XULTreeGridAccessible(nsIContent* aContent, DocAccessible* aDoc) : XULTreeAccessible(aContent, aDoc), xpcAccessibleTable(this) { + mFlags |= eTableAccessible; } //////////////////////////////////////////////////////////////////////////////// // XULTreeGridAccessible: nsISupports implementation NS_IMPL_ISUPPORTS_INHERITED1(XULTreeGridAccessible, XULTreeAccessible, nsIAccessibleTable) @@ -274,16 +275,18 @@ XULTreeGridAccessible::CreateTreeItemAcc //////////////////////////////////////////////////////////////////////////////// XULTreeGridRowAccessible:: XULTreeGridRowAccessible(nsIContent* aContent, DocAccessible* aDoc, Accessible* aTreeAcc, nsITreeBoxObject* aTree, nsITreeView* aTreeView, int32_t aRow) : XULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView, aRow) { + mFlags |= eTableRowAccessible; + mAccessibleCache.Init(kDefaultTreeCacheSize); } //////////////////////////////////////////////////////////////////////////////// // XULTreeGridRowAccessible: nsISupports and cycle collection implementation NS_IMPL_CYCLE_COLLECTION_INHERITED_1(XULTreeGridRowAccessible, XULTreeItemAccessibleBase,
--- a/accessible/tests/mochitest/common.js +++ b/accessible/tests/mochitest/common.js @@ -364,16 +364,19 @@ function testAccessibleTree(aAccOrElmOrI if (prop == "role") { is(roleToString(acc[prop]), roleToString(accTree[prop]), msg); } else if (prop == "states") { var statesObj = accTree[prop]; testStates(acc, statesObj.states, statesObj.extraStates, statesObj.absentStates, statesObj.absentExtraStates); + } else if (prop == "tagName") { + is(accTree[prop], acc.DOMNode.tagName, msg); + } else if (prop != "children") { is(acc[prop], accTree[prop], msg); } } // Test children. if ("children" in accTree && accTree["children"] instanceof Array) { var children = acc.children;
--- a/accessible/tests/mochitest/role/test_aria.html +++ b/accessible/tests/mochitest/role/test_aria.html @@ -110,17 +110,18 @@ "landmarked table should have nsIAccessibleTable"); if (accessibleTable) is(accessibleTable.getCellAt(0,0).firstChild.name, "hi", "no cell"); } ////////////////////////////////////////////////////////////////////////// // test gEmptyRoleMap - testRole("cell", ROLE_NOTHING); + testRole("buttontable_row", ROLE_NOTHING); + testRole("buttontable_cell", ROLE_NOTHING); // abstract roles var abstract_roles = ["composite", "landmark", "structure", "widget", "window", "input", "range", "select", "section", "sectionhead"]; for (a in abstract_roles) testRole(abstract_roles[a], ROLE_SECTION); @@ -270,18 +271,18 @@ <tr><td>hi<td></tr></table> <table role="navigation" id="navigation_table">navigation table <tr><td>hi<td></tr></table> <table role="search" id="search_table">search table <tr><td>hi<td></tr></table> <!-- test gEmptyRoleMap --> <table role="button"> - <tr> - <td id="cell">cell</td> + <tr id="buttontable_row"> + <td id="buttontable_cell">cell</td> </tr> </table> <!-- user agents must not map abstract roles to platform API --> <!-- test abstract base type roles --> <div role="composite" id="composite">composite</div> <div role="landmark" id="landmark">landmark</div> <div role="roletype" id="roletype">roletype</div>
--- a/accessible/tests/mochitest/tree/test_aria_grid.html +++ b/accessible/tests/mochitest/tree/test_aria_grid.html @@ -27,16 +27,134 @@ { TEXT_LEAF: [ ] } ] } ] } ] }, ] }; testAccessibleTree("grid", accTree); + ////////////////////////////////////////////////////////////////////////// + // crazy grids (mad mix of ARIA and HTML tables) + + accTree = { + role: ROLE_TABLE, + children: [ + { // div@role="row" + role: ROLE_ROW, + tagName: "DIV", + children: [ + { // caption text leaf + role: ROLE_TEXT_LEAF, + name: "caption", + children: [ ] + }, + { // th text leaf + role: ROLE_TEXT_LEAF, + name: "header1", + children: [ ] + }, + { // td@role="columnheader" + role: ROLE_COLUMNHEADER, + name: "header2", + children: [ { TEXT_LEAF: [ ] } ] + } + ] + } + ] + }; + testAccessibleTree("crazy_grid1", accTree); + + accTree = { + role: ROLE_TABLE, + children: [ + { // tr@role="row" + role: ROLE_ROW, + tagName: "TR", + children: [ + { // td text leaf + role: ROLE_TEXT_LEAF, + name: "cell1", + children: [ ] + }, + { // td@role="gridcell" + role: ROLE_GRID_CELL, + name: "cell2", + children: [ { TEXT_LEAF: [ ] } ] + } + ] + } + ] + }; + testAccessibleTree("crazy_grid2", accTree); + + accTree = { + role: ROLE_TABLE, + children: [ + { // div@role="row" + role: ROLE_ROW, + children: [ + { // div@role="gridcell" + role: ROLE_GRID_CELL, + children: [ + { // text leaf from presentational table + role: ROLE_TEXT_LEAF, + name: "cell3", + children: [ ] + }, + ] + } + ] + } + ] + }; + testAccessibleTree("crazy_grid3", accTree); + + accTree = { + role: ROLE_TABLE, + children: [ + { // div@role="row" + role: ROLE_ROW, + children: [ + { // div@role="gridcell" + role: ROLE_GRID_CELL, + children: [ + { // table + role: ROLE_TABLE, + children: [ + { // tr + role: ROLE_ROW, + children: [ + { // td + role: ROLE_CELL, + children: [ + { // caption text leaf of presentational table + role: ROLE_TEXT_LEAF, + name: "caption", + children: [ ] + }, + { // td text leaf of presentational table + role: ROLE_TEXT_LEAF, + name: "cell4", + children: [ ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }; + + testAccessibleTree("crazy_grid4", accTree); SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script> </head> @@ -54,10 +172,60 @@ <div id="grid" role="grid"> <div role="rowgroup"> <div role="row"> <div role="gridcell">cell</div> </div> </div> </div> + + <div id="crazy_grid1" role="grid"> + <div role="row"> + <table role="presentation"> + <caption>caption</caption> + <tr> + <th>header1</th> + <td role="columnheader">header2</td> + </tr> + </table> + </div> + </div> + + <div id="crazy_grid2" role="grid"> + <table role="presentation"> + <tr role="row"> + <td id="ct_cell1">cell1</td> + <td role="gridcell">cell2</td> + </tr> + </table> + </div> + + <div id="crazy_grid3" role="grid"> + <div role="row"> + <div role="gridcell"> + <table role="presentation"> + <tr> + <td>cell3</td> + </tr> + </table> + </div> + </div> + </div> + + <div id="crazy_grid4" role="grid"> + <div role="row"> + <div role="gridcell"> + <table> + <tr> + <td> + <table role="presentation"> + <caption>caption</caption> + <tr><td>cell4</td></tr> + </table> + </td> + </tr> + </table> + </div> + </div> + </div> </body> </html>
--- a/accessible/tests/mochitest/tree/test_brokencontext.html +++ b/accessible/tests/mochitest/tree/test_brokencontext.html @@ -22,26 +22,24 @@ // HTML table elements outside table context. ok(!isAccessible("tr_in_presentation_table"), "tr shouldn't be accessible"); ok(!isAccessible("th_in_presentation_table"), "th shouldn't be accessible"); ok(!isAccessible("td_in_presentation_table"), "td shouldn't be accessible"); var tree = { PUSHBUTTON: [ // table - { NOTHING: [ // tbody { NOTHING: [ // tr { NOTHING: [ // th { TEXT_LEAF: [ ] } ] }, { NOTHING: [ // td { TEXT_LEAF: [ ] } ] } - ] }, - ] }, + ] } ] }; testAccessibleTree("button_table", tree); //////////////////////////////////////////////////////////////////////////// // Styled as HTML table elements, accessible is created by tag name tree = { LINK: [ // a
new file mode 100644 --- /dev/null +++ b/b2g/app/BootAnimation.cpp @@ -0,0 +1,657 @@ +/* Copyright 2012 Mozilla Foundation and Mozilla contributors + * + * 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 <GLES2/gl2.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <algorithm> +#include <endian.h> +#include <fcntl.h> +#include <string> +#include <sys/mman.h> +#include <sys/stat.h> +#include <vector> +#include "mozilla/Util.h" +#include "mozilla/NullPtr.h" +#include "png.h" + +#include "android/log.h" +#include "ui/FramebufferNativeWindow.h" +#include "hardware_legacy/power.h" + +#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) +#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args) +#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args) + +using namespace android; +using namespace mozilla; +using namespace std; + +static sp<FramebufferNativeWindow> gNativeWindow; +static pthread_t sAnimationThread; +static bool sRunAnimation; + +/* See http://www.pkware.com/documents/casestudies/APPNOTE.TXT */ +struct local_file_header { + uint32_t signature; + uint16_t min_version; + uint16_t general_flag; + uint16_t compression; + uint16_t lastmod_time; + uint16_t lastmod_date; + uint32_t crc32; + uint32_t compressed_size; + uint32_t uncompressed_size; + uint16_t filename_size; + uint16_t extra_field_size; + char data[0]; + + uint32_t GetDataSize() const + { + return letoh32(uncompressed_size); + } + + uint32_t GetSize() const + { + /* XXX account for data descriptor */ + return sizeof(local_file_header) + letoh16(filename_size) + + letoh16(extra_field_size) + GetDataSize(); + } + + const char * GetData() const + { + return data + letoh16(filename_size) + letoh16(extra_field_size); + } +} __attribute__((__packed__)); + +struct data_descriptor { + uint32_t crc32; + uint32_t compressed_size; + uint32_t uncompressed_size; +} __attribute__((__packed__)); + +struct cdir_entry { + uint32_t signature; + uint16_t creator_version; + uint16_t min_version; + uint16_t general_flag; + uint16_t compression; + uint16_t lastmod_time; + uint16_t lastmod_date; + uint32_t crc32; + uint32_t compressed_size; + uint32_t uncompressed_size; + uint16_t filename_size; + uint16_t extra_field_size; + uint16_t file_comment_size; + uint16_t disk_num; + uint16_t internal_attr; + uint32_t external_attr; + uint32_t offset; + char data[0]; + + uint32_t GetDataSize() const + { + return letoh32(compressed_size); + } + + uint32_t GetSize() const + { + return sizeof(cdir_entry) + letoh16(filename_size) + + letoh16(extra_field_size) + letoh16(file_comment_size); + } + + bool Valid() const + { + return signature == htole32(0x02014b50); + } +} __attribute__((__packed__)); + +struct cdir_end { + uint32_t signature; + uint16_t disk_num; + uint16_t cdir_disk; + uint16_t disk_entries; + uint16_t cdir_entries; + uint32_t cdir_size; + uint32_t cdir_offset; + uint16_t comment_size; + char comment[0]; + + bool Valid() const + { + return signature == htole32(0x06054b50); + } +} __attribute__((__packed__)); + +/* We don't have access to libjar and the zip reader in android + * doesn't quite fit what we want to do. */ +class ZipReader { + const char *mBuf; + const cdir_end *mEnd; + const char *mCdir_limit; + uint32_t mBuflen; + +public: + ZipReader() : mBuf(nullptr) {} + ~ZipReader() { + if (mBuf) + munmap((void *)mBuf, mBuflen); + } + + bool OpenArchive(const char *path) + { + int fd; + do { + fd = open(path, O_RDONLY); + } while (fd == -1 && errno == EINTR); + if (fd == -1) + return false; + + struct stat sb; + if (fstat(fd, &sb) == -1 || sb.st_size < sizeof(cdir_end)) { + close(fd); + return false; + } + + mBuflen = sb.st_size; + mBuf = (char *)mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + + if (!mBuf) { + return false; + } + + madvise(mBuf, sb.st_size, MADV_SEQUENTIAL); + + mEnd = (cdir_end *)(mBuf + mBuflen - sizeof(cdir_end)); + while (!mEnd->Valid() && + (char *)mEnd > mBuf) { + mEnd = (cdir_end *)((char *)mEnd - 1); + } + + mCdir_limit = mBuf + letoh32(mEnd->cdir_offset) + letoh32(mEnd->cdir_size); + + if (!mEnd->Valid() || mCdir_limit > (char *)mEnd) { + munmap((void *)mBuf, mBuflen); + mBuf = nullptr; + return false; + } + + return true; + } + + /* Pass null to get the first cdir entry */ + const cdir_entry * GetNextEntry(const cdir_entry *prev) + { + const cdir_entry *entry; + if (prev) + entry = (cdir_entry *)((char *)prev + prev->GetSize()); + else + entry = (cdir_entry *)(mBuf + letoh32(mEnd->cdir_offset)); + + if (((char *)entry + entry->GetSize()) > mCdir_limit || + !entry->Valid()) + return nullptr; + return entry; + } + + string GetEntryName(const cdir_entry *entry) + { + uint16_t len = letoh16(entry->filename_size); + + string name; + name.append(entry->data, len); + return name; + } + + const local_file_header * GetLocalEntry(const cdir_entry *entry) + { + const local_file_header * data = + (local_file_header *)(mBuf + letoh32(entry->offset)); + if (((char *)data + data->GetSize()) > (char *)mEnd) + return nullptr; + return data; + } +}; + +struct AnimationFrame { + char path[256]; + char *buf; + uint16_t width; + uint16_t height; + const local_file_header *file; + + AnimationFrame() : buf(nullptr) {} + AnimationFrame(const AnimationFrame &frame) : buf(nullptr) { + strncpy(path, frame.path, sizeof(path)); + file = frame.file; + } + ~AnimationFrame() + { + if (buf) + free(buf); + } + + bool operator<(const AnimationFrame &other) const + { + return strcmp(path, other.path) < 0; + } + + void ReadPngFrame(); +}; + +struct AnimationPart { + int32_t count; + int32_t pause; + char path[256]; + vector<AnimationFrame> frames; +}; + +using namespace android; + +struct RawReadState { + const char *start; + uint32_t offset; + uint32_t length; +}; + +static void +RawReader(png_structp png_ptr, png_bytep data, png_size_t length) +{ + RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr); + if (length > (state->length - state->offset)) + png_err(png_ptr); + + memcpy(data, state->start + state->offset, length); + state->offset += length; +} + +void +AnimationFrame::ReadPngFrame() +{ + png_structp pngread = png_create_read_struct(PNG_LIBPNG_VER_STRING, + nullptr, nullptr, nullptr); + + png_infop pnginfo = png_create_info_struct(pngread); + + RawReadState state; + state.start = file->GetData(); + state.length = file->GetDataSize(); + state.offset = 0; + + png_set_read_fn(pngread, &state, RawReader); + + setjmp(png_jmpbuf(pngread)); + + png_read_info(pngread, pnginfo); + + width = png_get_image_width(pngread, pnginfo); + height = png_get_image_height(pngread, pnginfo); + buf = (char *)malloc(width * height * 3); + + vector<char *> rows(height + 1); + uint32_t stride = width * 3; + for (int i = 0; i < height; i++) { + rows[i] = buf + (stride * i); + } + rows[height] = nullptr; + png_set_palette_to_rgb(pngread); + png_read_image(pngread, (png_bytepp)&rows.front()); + png_destroy_read_struct(&pngread, &pnginfo, nullptr); +} + +static const EGLint kEGLConfigAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE +}; + +static bool +CreateConfig(EGLConfig* aConfig, EGLDisplay display, int format) +{ + EGLConfig configs[64]; + EGLint ncfg = ArrayLength(configs); + + if (!eglChooseConfig(display, kEGLConfigAttribs, + configs, ncfg, &ncfg) || + ncfg < 1) { + return false; + } + + for (int j = 0; j < ncfg; ++j) { + EGLConfig config = configs[j]; + EGLint id; + + if (eglGetConfigAttrib(display, config, + EGL_NATIVE_VISUAL_ID, &id) && + id > 0 && id == format) + { + *aConfig = config; + return true; + } + } + return false; +} + +static void * +AnimationThread(void *) +{ + ZipReader reader; + if (!reader.OpenArchive("/system/media/bootanimation.zip")) { + LOGW("Could not open boot animation"); + return nullptr; + } + + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(display, nullptr, nullptr); + + int format; + ANativeWindow const * const window = gNativeWindow.get(); + window->query(window, NATIVE_WINDOW_FORMAT, &format); + + EGLConfig config = NULL; + CreateConfig(&config, display, format); + if (!config) { + LOGW("Could not find config for pixel format"); + return nullptr; + } + + EGLSurface surface = eglCreateWindowSurface(display, config, gNativeWindow.get(), nullptr); + + const cdir_entry *entry = nullptr; + const local_file_header *file = nullptr; + while ((entry = reader.GetNextEntry(entry))) { + string name = reader.GetEntryName(entry); + if (!name.compare("desc.txt")) { + file = reader.GetLocalEntry(entry); + break; + } + } + + if (!file) { + LOGW("Could not find desc.txt in boot animation"); + return nullptr; + } + + string descCopy; + descCopy.append(file->GetData(), entry->GetDataSize()); + int32_t width, height, fps; + const char *line = descCopy.c_str(); + const char *end; + bool headerRead = true; + vector<AnimationPart> parts; + + /* + * bootanimation.zip + * + * This is the boot animation file format that Android uses. + * It's a zip file with a directories containing png frames + * and a desc.txt that describes how they should be played. + * + * desc.txt contains two types of lines + * 1. [width] [height] [fps] + * There is one of these lines per bootanimation. + * If the width and height are smaller than the screen, + * the frames are centered on a black background. + * XXX: Currently we stretch instead of centering the frame. + * 2. p [count] [pause] [path] + * This describes one animation part. + * Each animation part is played in sequence. + * An animation part contains all the files/frames in the + * directory specified in [path] + * [count] indicates the number of times this part repeats. + * [pause] indicates the number of frames that this part + * should pause for after playing the full sequence but + * before repeating. + */ + + do { + end = strstr(line, "\n"); + + AnimationPart part; + if (headerRead && + sscanf(line, "%d %d %d", &width, &height, &fps) == 3) { + headerRead = false; + } else if (sscanf(line, "p %d %d %s", + &part.count, &part.pause, part.path)) { + parts.push_back(part); + } + } while (end && *(line = end + 1)); + + for (uint32_t i = 0; i < parts.size(); i++) { + AnimationPart &part = parts[i]; + entry = nullptr; + char search[256]; + snprintf(search, sizeof(search), "%s/", part.path); + while ((entry = reader.GetNextEntry(entry))) { + string name = reader.GetEntryName(entry); + if (name.find(search) || + !entry->GetDataSize() || + name.length() >= 256) + continue; + + part.frames.push_back(); + AnimationFrame &frame = part.frames.back(); + strcpy(frame.path, name.c_str()); + frame.file = reader.GetLocalEntry(entry); + } + + sort(part.frames.begin(), part.frames.end()); + } + + static EGLint gContextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE, 0 + }; + EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, gContextAttribs); + + eglMakeCurrent(display, surface, surface, context); + glEnable(GL_TEXTURE_2D); + + const char *vsString = + "attribute vec2 aPosition; " + "attribute vec2 aTexCoord; " + "varying vec2 vTexCoord; " + "void main() { " + " gl_Position = vec4(aPosition, 0.0, 1.0); " + " vTexCoord = aTexCoord; " + "}"; + + const char *fsString = + "precision mediump float; " + "varying vec2 vTexCoord; " + "uniform sampler2D sTexture; " + "void main() { " + " gl_FragColor = vec4(texture2D(sTexture, vTexCoord).rgb, 1.0); " + "}"; + + GLint status; + GLuint vsh = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vsh, 1, &vsString, nullptr); + glCompileShader(vsh); + glGetShaderiv(vsh, GL_COMPILE_STATUS, &status); + if (!status) { + LOGE("Failed to compile vertex shader"); + return nullptr; + } + + GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fsh, 1, &fsString, nullptr); + glCompileShader(fsh); + glGetShaderiv(fsh, GL_COMPILE_STATUS, &status); + if (!status) { + LOGE("Failed to compile fragment shader"); + return nullptr; + } + + GLuint programId = glCreateProgram(); + glAttachShader(programId, vsh); + glAttachShader(programId, fsh); + + glLinkProgram(programId); + glGetProgramiv(programId, GL_LINK_STATUS, &status); + if (!status) { + LOG("Failed to link program"); + return nullptr; + } + + GLint positionLoc = glGetAttribLocation(programId, "aPosition"); + GLint texCoordLoc = glGetAttribLocation(programId, "aTexCoord"); + GLint textureLoc = glGetUniformLocation(programId, "sTexture"); + + glUseProgram(programId); + + GLfloat texCoords[] = { 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f }; + + GLfloat vCoords[] = { -1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f }; + + GLuint rectBuf, texBuf; + glGenBuffers(1, &rectBuf); + glGenBuffers(1, &texBuf); + + GLuint tex; + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glEnableVertexAttribArray(positionLoc); + glBindBuffer(GL_ARRAY_BUFFER, rectBuf); + glBufferData(GL_ARRAY_BUFFER, sizeof(vCoords), vCoords, GL_STATIC_DRAW); + glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glEnableVertexAttribArray(texCoordLoc); + glBindBuffer(GL_ARRAY_BUFFER, texBuf); + glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW); + glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glUniform1i(textureLoc, 0); + + uint32_t frameDelayUs = 1000000 / fps; + + for (uint32_t i = 0; i < parts.size(); i++) { + AnimationPart &part = parts[i]; + + uint32_t j = 0; + while (sRunAnimation && (!part.count || j++ < part.count)) { + for (uint32_t k = 0; k < part.frames.size(); k++) { + struct timeval tv1, tv2; + gettimeofday(&tv1, nullptr); + AnimationFrame &frame = part.frames[k]; + if (!frame.buf) { + frame.ReadPngFrame(); + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + frame.width, frame.height, 0, + GL_RGB, GL_UNSIGNED_BYTE, frame.buf); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + gettimeofday(&tv2, nullptr); + + timersub(&tv2, &tv1, &tv2); + + if (tv2.tv_usec < frameDelayUs) { + usleep(frameDelayUs - tv2.tv_usec); + } else { + LOGW("Frame delay is %d us but decoding took %d us", frameDelayUs, tv2.tv_usec); + } + + eglSwapBuffers(display, surface); + + if (part.count && j >= part.count) { + free(frame.buf); + frame.buf = nullptr; + } + } + usleep(frameDelayUs * part.pause); + } + } + glBindTexture(GL_TEXTURE_2D, 0); + glUseProgram(0); + glDeleteTextures(1, &tex); + glDeleteBuffers(1, &texBuf); + glDeleteBuffers(1, &rectBuf); + glDeleteProgram(programId); + glDeleteShader(fsh); + glDeleteShader(vsh); + + eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + eglDestroyContext(display, context); + eglDestroySurface(display, surface); + return nullptr; +} + +static int +CancelBufferNoop(ANativeWindow* aWindow, android_native_buffer_t* aBuffer) +{ + return 0; +} + +__attribute__ ((visibility ("default"))) +FramebufferNativeWindow* +NativeWindow() +{ + if (gNativeWindow.get()) { + return gNativeWindow.get(); + } + + // Some gralloc HALs need this in order to open the + // framebuffer device after we restart with the screen off. + // + // NB: this *must* run BEFORE allocating the + // FramebufferNativeWindow. Do not separate these two C++ + // statements. + set_screen_state(1); + + // We (apparently) don't have a way to tell if allocating the + // fbs succeeded or failed. + gNativeWindow = new FramebufferNativeWindow(); + + // Bug 776742: FrambufferNativeWindow doesn't set the cancelBuffer + // function pointer, causing EGL to segfault when the window surface + // is destroyed (i.e. on process exit). This workaround stops us + // from hard crashing in that situation. + gNativeWindow->cancelBuffer = CancelBufferNoop; + + sRunAnimation = true; + pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr); + + return gNativeWindow.get(); +} + + +__attribute__ ((visibility ("default"))) +void +StopBootAnimation() +{ + if (sRunAnimation) { + sRunAnimation = false; + pthread_join(sAnimationThread, nullptr); + } +}
new file mode 100644 --- /dev/null +++ b/b2g/app/BootAnimation.h @@ -0,0 +1,17 @@ +#ifndef BOOTANIMATION_H +#define BOOTANIMATION_H + +namespace android { +class FramebufferNativeWindow; +} + +/* This returns a FramebufferNativeWindow if one exists. + * If not, one is created and the boot animation is started. */ +__attribute__ ((weak)) +android::FramebufferNativeWindow* NativeWindow(); + +/* This stops the boot animation if it's still running. */ +__attribute__ ((weak)) +void StopBootAnimation(); + +#endif /* BOOTANIMATION_H */
--- a/b2g/app/Makefile.in +++ b/b2g/app/Makefile.in @@ -19,16 +19,31 @@ ifndef LIBXUL_SDK ifneq ($(GAIADIR),) PROGRAM=$(MOZ_APP_NAME)-bin$(BIN_SUFFIX) else PROGRAM=$(MOZ_APP_NAME)$(BIN_SUFFIX) endif CPPSRCS = nsBrowserApp.cpp +ifeq (gonk,$(MOZ_WIDGET_TOOLKIT)) +CPPSRCS += BootAnimation.cpp +LIBS += \ + -lGLESv2 \ + -lEGL \ + -lui \ + -lhardware_legacy \ + -lhardware \ + -lcutils \ + $(DEPTH)/media/libpng/$(LIB_PREFIX)mozpng.$(LIB_SUFFIX) \ + $(MOZ_ZLIB_LIBS) \ + $(NULL) +OS_LDFLAGS += -Wl,--export-dynamic +endif + LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build LOCAL_INCLUDES += -I$(DEPTH)/build DEFINES += -DXPCOM_GLUE STL_FLAGS=
--- a/b2g/app/nsBrowserApp.cpp +++ b/b2g/app/nsBrowserApp.cpp @@ -23,16 +23,21 @@ #include "nsStringGlue.h" #ifdef XP_WIN // we want a wmain entry point #include "nsWindowsWMain.cpp" #define snprintf _snprintf #define strcasecmp _stricmp #endif + +#ifdef MOZ_WIDGET_GONK +#include "BootAnimation.h" +#endif + #include "BinaryPath.h" #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL #include "mozilla/Telemetry.h" static void Output(const char *fmt, ... ) { @@ -134,16 +139,21 @@ static int do_main(int argc, char* argv[ Output("Couldn't set %s.\n", appEnv); return 255; } argv[2] = argv[0]; argv += 2; argc -= 2; } +#ifdef MOZ_WIDGET_GONK + /* Called to start the boot animation */ + (void) NativeWindow(); +#endif + if (appini) { nsXREAppData *appData; rv = XRE_CreateAppData(appini, &appData); if (NS_FAILED(rv)) { Output("Couldn't read application.ini"); return 255; } int result = XRE_main(argc, argv, appData, 0);
--- a/b2g/branding/official/locales/en-US/brand.dtd +++ b/b2g/branding/official/locales/en-US/brand.dtd @@ -1,8 +1,8 @@ <!-- 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/. --> -<!ENTITY brandShortName "B2G"> -<!ENTITY brandFullName "Mozilla B2G"> -<!ENTITY vendorShortName "Mozilla"> -<!ENTITY logoTrademark "B2G and the B2G logos are trademarks of the Mozilla Foundation."> +<!ENTITY brandShortName "Firefox"> +<!ENTITY brandFullName "Mozilla Firefox"> +<!ENTITY vendorShortName "Mozilla"> +<!ENTITY logoTrademark "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
--- a/b2g/branding/official/locales/en-US/brand.properties +++ b/b2g/branding/official/locales/en-US/brand.properties @@ -1,6 +1,6 @@ # 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/. -brandShortName=B2G -brandFullName=Mozilla B2G +brandShortName=Firefox +brandFullName=Mozilla Firefox
--- a/b2g/branding/unofficial/locales/en-US/brand.dtd +++ b/b2g/branding/unofficial/locales/en-US/brand.dtd @@ -1,8 +1,8 @@ <!-- 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/. --> -<!ENTITY brandShortName "B2G"> -<!ENTITY brandFullName "Mozilla B2G"> +<!ENTITY brandShortName "Firefox"> +<!ENTITY brandFullName "Mozilla Firefox"> <!ENTITY vendorShortName "Mozilla"> -<!ENTITY logoTrademark ""> +<!ENTITY logoTrademark "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
--- a/b2g/branding/unofficial/locales/en-US/brand.properties +++ b/b2g/branding/unofficial/locales/en-US/brand.properties @@ -1,6 +1,6 @@ # 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/. -brandShortName=B2G -brandFullName=Mozilla B2G +brandShortName=Firefox +brandFullName=Mozilla Firefox
--- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -398,16 +398,18 @@ var shell = { DOMApplicationRegistry.allAppsLaunchable = true; this.sendEvent(window, 'ContentStart'); content.addEventListener('load', function shell_homeLoaded() { content.removeEventListener('load', shell_homeLoaded); shell.isHomeLoaded = true; + Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); + if ('pendingChromeEvents' in shell) { shell.pendingChromeEvents.forEach((shell.sendChromeEvent).bind(shell)); } delete shell.pendingChromeEvents; }); break; case 'MozApplicationManifest':
--- a/b2g/components/ContentPermissionPrompt.js +++ b/b2g/components/ContentPermissionPrompt.js @@ -1,26 +1,30 @@ /* 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/. */ +"use strict" + let DEBUG = 0; let debug; if (DEBUG) { debug = function (s) { dump("-*- ContentPermissionPrompt: " + s + "\n"); }; } else { debug = function (s) {}; } const Ci = Components.interfaces; const Cr = Components.results; const Cu = Components.utils; const Cc = Components.classes; +const PROMPT_FOR_UNKNOWN = ['geolocation']; + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Webapps.jsm"); Cu.import("resource://gre/modules/AppsUtils.jsm"); Cu.import("resource://gre/modules/PermissionsInstaller.jsm"); var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager); var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); @@ -31,50 +35,50 @@ XPCOMUtils.defineLazyServiceGetter(this, "nsIDOMPermissionSettings"); function rememberPermission(aPermission, aPrincipal) { function convertPermToAllow(aPerm, aPrincipal) { let type = permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm); - if (type == Ci.nsIPermissionManager.PROMPT_ACTION) { + if (type == Ci.nsIPermissionManager.PROMPT_ACTION || + (type == Ci.nsIPermissionManager.UNKNOWN_ACTION && + PROMPT_FOR_UNKNOWN.indexOf(aPermission) >= 0)) { permissionManager.addFromPrincipal(aPrincipal, aPerm, Ci.nsIPermissionManager.ALLOW_ACTION); } } // Expand the permission to see if we have multiple access properties to convert let access = PermissionsTable[aPermission].access; if (access) { for (let idx in access) { convertPermToAllow(aPermission + "-" + access[idx], aPrincipal); } - } - else { + } else { convertPermToAllow(aPermission, aPrincipal); } } function ContentPermissionPrompt() {} ContentPermissionPrompt.prototype = { handleExistingPermission: function handleExistingPermission(request) { - let promptForUnknown = ['geolocation']; let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access : request.type; let result = Services.perms.testExactPermissionFromPrincipal(request.principal, access); if (result == Ci.nsIPermissionManager.ALLOW_ACTION) { request.allow(); return true; } if (result == Ci.nsIPermissionManager.DENY_ACTION || - result == Ci.nsIPermissionManager.UNKNOWN_ACTION && promptForUnknown.indexOf(access) < 0) { + result == Ci.nsIPermissionManager.UNKNOWN_ACTION && PROMPT_FOR_UNKNOWN.indexOf(access) < 0) { request.cancel(); return true; } return false; }, _id: 0, prompt: function(request) {
--- a/b2g/components/UpdatePrompt.js +++ b/b2g/components/UpdatePrompt.js @@ -255,20 +255,33 @@ UpdatePrompt.prototype = { case "restart": this.finishUpdate(); this._update = null; break; } }, downloadUpdate: function UP_downloadUpdate(aUpdate) { + if (!aUpdate) { + aUpdate = Services.um.activeUpdate; + if (!aUpdate) { + log("No active update found to download"); + return; + } + } + Services.aus.downloadUpdate(aUpdate, true); Services.aus.addDownloadListener(this); }, + handleDownloadCancel: function UP_handleDownloadCancel() { + log("Pausing download"); + Services.aus.pauseDownload(); + }, + finishUpdate: function UP_finishUpdate() { if (!this._update.isOSUpdate) { // Standard gecko+gaia updates will just need to restart the process this.restartProcess(); return; } let osApplyToDir; @@ -342,16 +355,19 @@ UpdatePrompt.prototype = { switch (detail.type) { case "force-update-check": this.forceUpdateCheck(); break; case "update-available-result": this.handleAvailableResult(detail); this._update = null; break; + case "update-download-cancel": + this.handleDownloadCancel(); + break; case "update-prompt-apply-result": this.handleApplyPromptResult(detail); break; } }, appsUpdated: function UP_appsUpdated(aApps) { log("appsUpdated: " + aApps.length + " apps to update");
--- a/b2g/installer/package-manifest.in +++ b/b2g/installer/package-manifest.in @@ -49,17 +49,16 @@ #ifndef MOZ_STATIC_JS @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@ #endif @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@ @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@ -@BINPATH@/@DLL_PREFIX@soundtouch@DLL_SUFFIX@ #ifdef XP_MACOSX @BINPATH@/XUL #else @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@ #endif #ifdef XP_MACOSX @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/ #else
--- a/b2g/locales/Makefile.in +++ b/b2g/locales/Makefile.in @@ -8,25 +8,16 @@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ relativesrcdir = @relativesrcdir@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/config.mk -ifdef LOCALE_MERGEDIR -vpath crashreporter%.ini $(LOCALE_MERGEDIR)/b2g/crashreporter -endif -vpath crashreporter%.ini $(LOCALE_SRCDIR)/crashreporter -ifdef LOCALE_MERGEDIR -vpath crashreporter%.ini @srcdir@/en-US/crashreporter -endif - - SUBMAKEFILES += \ $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \ $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales/Makefile \ $(NULL) # This makefile uses variable overrides from the libs-% target to # build non-default locales to non-default dist/ locations. Be aware! @@ -80,22 +71,25 @@ install:: $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(DESTDIR)$(mozappdir)/defaults/existing-profile-defaults.js; \ fi NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD)) libs-%: $(NSINSTALL) -D $(DIST)/install @$(MAKE) -C ../../toolkit/locales libs-$* - @$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$* - @$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$* @$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR) @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* +# Tailored target to just add the chrome processing for multi-locale builds +chrome-%: + @$(MAKE) -C ../../toolkit/locales chrome-$* + @$(MAKE) chrome AB_CD=$* + @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$* repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe repackage-win32-installer: $(call ESCAPE_SPACE,$(WIN32_INSTALLER_IN)) $(SUBMAKEFILES) libs-$(AB_CD) @echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)." $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export $(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/setup.exe l10ngen/7zSD.sfx $(MAKE) repackage-zip \ AB_CD=$(AB_CD) \ @@ -113,50 +107,29 @@ repackage-win32-installer-%: ; endif clobber-zip: $(RM) $(STAGEDIST)/chrome/$(AB_CD).jar \ $(STAGEDIST)/chrome/$(AB_CD).manifest \ $(STAGEDIST)/defaults/pref/b2g-l10n.js $(STAGEDIST)/dictionaries \ - $(STAGEDIST)/hyphenation \ $(STAGEDIST)/defaults/profile \ $(STAGEDIST)/chrome/$(AB_CD) langpack: langpack-$(AB_CD) # This is a generic target that will make a langpack, repack ZIP (+tarball) # builds, and repack an installer if applicable. It is called from the # tinderbox scripts. Alter it with caution. installers-%: clobber-% langpack-% repackage-win32-installer-% repackage-zip-% @echo "repackaging done" -ifdef MOZ_UPDATER -libs:: $(call MERGE_FILE,updater/updater.ini) -ifeq ($(OS_ARCH),WINNT) - cat $< $(srcdir)/../installer/windows/nsis/updater_append.ini | \ - sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \ - sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \ - $(FINAL_TARGET)/updater.ini -else - cat $< | \ - sed -e "s/^InfoText=/Info=/" -e "s/^TitleText=/Title=/" | \ - sed -e "s/%MOZ_APP_DISPLAYNAME%/$(MOZ_APP_DISPLAYNAME)/" > \ - $(FINAL_TARGET)/updater.ini -endif -endif - -ifdef MOZ_CRASHREPORTER -libs:: crashreporter-override.ini - $(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET) -endif - # When we unpack b2g on MacOS X the platform.ini and application.ini are in slightly # different locations that on all other platforms ifeq (Darwin, $(OS_ARCH)) ifdef LIBXUL_SDK GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/../Frameworks/XUL.framework/Versions/$(MOZILLA_VERSION)/platform.ini" else GECKO_PLATFORM_INI_PATH="$(STAGEDIST)/platform.ini" endif
--- a/b2g/locales/all-locales +++ b/b2g/locales/all-locales @@ -1,45 +1,2 @@ -ar -be -ca -cs -da -de -el -es-AR es-ES -et -eu -fa -fi -fr -fy-NL -ga-IE -gd -gl -he -hu -id -it -ja -ja-JP-mac -ko -lt -nb-NO -nl -nn-NO -pa-IN -pl pt-BR -pt-PT -ro -ru -sk -sl -sq -sr -th -tr -uk -vi -zh-CN -zh-TW
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/about.dtd +++ /dev/null @@ -1,22 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!ENTITY aboutPage.title "About &brandShortName;"> -<!ENTITY aboutPage.faq.label "FAQ"> -<!ENTITY aboutPage.support.label "Support"> -<!ENTITY aboutPage.privacyPolicy.label "Privacy Policy"> -<!ENTITY aboutPage.rights.label "Know Your Rights"> -<!ENTITY aboutPage.relNotes.label "Release Notes"> -<!ENTITY aboutPage.credits.label "Credits"> -<!ENTITY aboutPage.checkForUpdates.button "Check for Updates"> -<!ENTITY aboutPage.checkForUpdates.checking "Looking for updates…"> -<!ENTITY aboutPage.checkForUpdates.none "No updates available"> -<!ENTITY aboutPage.checkForUpdates.found "Update available"> - - -<!-- LOCALIZATION NOTE: - These strings are concatenated in order. Unneeded strings may be left blank. ---> -<!ENTITY aboutPage.licenseLink "Licensing information"> -<!ENTITY aboutPage.licenseLinkSuffix ".">
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/aboutCertError.dtd +++ /dev/null @@ -1,38 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!ENTITY % brandDTD - SYSTEM "chrome://branding/locale/brand.dtd"> - %brandDTD; - -<!-- These strings are used by Firefox's custom about:certerror page, -a replacement for the standard security certificate errors produced -by NSS/PSM via netError.xhtml. --> - -<!ENTITY certerror.pagetitle "Untrusted Connection"> -<!ENTITY certerror.longpagetitle "This Connection is Untrusted"> - -<!-- Localization note (certerror.introPara1) - The string "#1" will -be replaced at runtime with the name of the server to which the user -was trying to connect. --> -<!ENTITY certerror.introPara1 "You have asked &brandShortName; to connect -securely to <b>#1</b>, but we can't confirm that your connection is secure."> - -<!ENTITY certerror.whatShouldIDo.heading "What Should I Do?"> -<!ENTITY certerror.whatShouldIDo.content "If you usually connect to -this site without problems, this error could mean that someone is -trying to impersonate the site, and you shouldn't continue."> -<!ENTITY certerror.getMeOutOfHere.label "Get me out of here!"> - -<!ENTITY certerror.expert.heading "I Understand the Risks"> -<!ENTITY certerror.expert.content "If you understand what's going on, you -can tell &brandShortName; to start trusting this site's identification. -<b>Even if you trust the site, this error could mean that someone is -tampering with your connection.</b>"> -<!ENTITY certerror.expert.contentPara2 "Don't add an exception unless -you know there's a good reason why this site doesn't use trusted identification."> -<!ENTITY certerror.addTemporaryException.label "Visit site"> -<!ENTITY certerror.addPermanentException.label "Add permanent exception"> - -<!ENTITY certerror.technical.heading "Technical Details">
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/notification.dtd +++ /dev/null @@ -1,12 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - -<!-- - LOCALIZATION NOTE (geolocation.learnMore): Use the - unicode ellipsis char, \u2026, - or use "..." unless \u2026 doesn't suit traditions in your - locale. ---> -<!ENTITY geolocation.learnMore "Learn More…">
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/overrides/passwordmgr.properties +++ /dev/null @@ -1,38 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -rememberValue = Use Password Manager to remember this value. -rememberPassword = Use Password Manager to remember this password. -savePasswordTitle = Confirm -# 1st string is product name, 2nd is the username for the login, 3rd is the -# login's hostname. Note that long usernames may be truncated. -saveLoginText = Do you want %1$S to remember the password for "%2$S" on %3$S? -# 1st string is product name, 2nd is the login's hostname -saveLoginTextNoUsername = Do you want %1$S to remember this password on %2$S? -notNowButtonText = &Not Now -notifyBarNotNowButtonText = Not Now -notifyBarNotNowButtonAccessKey = -neverForSiteButtonText = Ne&ver for This Site -notifyBarNeverForSiteButtonText = Never -notifyBarNeverForSiteButtonAccessKey = -rememberButtonText = &Remember -notifyBarRememberButtonText = Remember -notifyBarRememberButtonAccessKey = -passwordChangeTitle = Confirm Password Change -passwordChangeText = Would you like to change the stored password for %S? -passwordChangeTextNoUser = Would you like to change the stored password for this login? -notifyBarChangeButtonText = Change -notifyBarChangeButtonAccessKey = -notifyBarDontChangeButtonText = Don't Change -notifyBarDontChangeButtonAccessKey = -userSelectText = Please confirm which user you are changing the password for -hidePasswords=Hide Passwords -hidePasswordsAccessKey=P -showPasswords=Show Passwords -showPasswordsAccessKey=P -noMasterPasswordPrompt=Are you sure you wish to show your passwords? -removeAllPasswordsPrompt=Are you sure you wish to remove all passwords? -removeAllPasswordsTitle=Remove all passwords -loginsSpielAll=Passwords for the following sites are stored on your computer: -loginsSpielFiltered=The following passwords match your search:
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/phishing.dtd +++ /dev/null @@ -1,29 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!ENTITY safeb.palm.warning.title "Suspected Web Forgery"> - -<!ENTITY safeb.palm.message.p1 "This page has been reported as a web forgery designed to trick users into sharing personal or financial information. Entering any personal information on this page may result in identity theft or other fraud.  "> -<!ENTITY safeb.palm.message.p1.linkText "Read more »"> -<!ENTITY safeb.palm.p1.linkStatusText "Read more …"> - -<!ENTITY safeb.palm.message.p2.start "These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust. You can find out more about "> -<!ENTITY safeb.palm.message.p2.linkText "how &brandShortName; protects you"> -<!ENTITY safeb.palm.message.p2.end " from phishing attacks."> - -<!ENTITY safeb.palm.accept.label "Get me out of here!"> -<!ENTITY safeb.palm.accept.statustext "Navigate to my home page"> -<!ENTITY safeb.palm.decline.label "Ignore this warning"> -<!ENTITY safeb.palm.decline.statustext "Close warning" > -<!ENTITY safeb.palm.notforgery.label2 "This isn't a web forgery…"> -<!ENTITY safeb.palm.reportPage.label "Why was this page blocked?"> - -<!ENTITY safeb.blocked.malwarePage.title "Reported Attack Page!"> -<!-- Localization note (safeb.blocked.malware.shortDesc) - Please don't translate the contents of the <span id="malware_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) --> -<!ENTITY safeb.blocked.malwarePage.shortDesc "This web page at <span id='malware_sitename'/> has been reported as an attack page and has been blocked based on your security preferences."> -<!ENTITY safeb.blocked.malwarePage.longDesc "<p>Attack pages try to install programs that steal private information, use your computer to attack others, or damage your system.</p><p>Some attack pages intentionally distribute harmful software, but many are compromised without the knowledge or permission of their owners.</p>"> - -<!ENTITY safeb.blocked.phishingPage.title2 "Suspected Web Forgery!"> -<!ENTITY safeb.blocked.phishingPage.shortDesc2 "Entering any personal information on this page may result in identity theft or other fraud."> -<!ENTITY safeb.blocked.phishingPage.longDesc2 "<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>">
deleted file mode 100644 --- a/b2g/locales/en-US/chrome/webapps.dtd +++ /dev/null @@ -1,11 +0,0 @@ -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!ENTITY webapps.title.placeholder "Enter a title"> -<!ENTITY webapps.permissions "Allow access:"> -<!ENTITY webapps.perm.geolocation "Location-aware browsing"> -<!ENTITY webapps.perm.offline "Offline data storage"> -<!ENTITY webapps.perm.notifications "Desktop notifications"> -<!ENTITY webapps.perm.requestedHint "(requested)"> -<!ENTITY webapps.add-homescreen "Add to home screen">
deleted file mode 100644 --- a/b2g/locales/en-US/crashreporter/crashreporter-override.ini +++ /dev/null @@ -1,14 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# This file is in the UTF-8 encoding -[Strings] -# LOCALIZATION NOTE (CrashReporterProductErrorText2): %s is replaced with another string containing detailed information. -CrashReporterProductErrorText2=B2G has crashed. Unfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s -CrashReporterDescriptionText2=B2G has crashed. Your tabs will be listed on the B2G Start page when you restart.\n\nPlease help us fix the problem! -# LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name. -CheckSendReport=Send %s a crash report -CheckIncludeURL=Include the page address -Quit2=Quit B2G -Restart=Restart B2G
deleted file mode 100644 --- a/b2g/locales/en-US/installer/setup.ini +++ /dev/null @@ -1,21 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -; This file is in the UTF-8 encoding -[Strings] -AppShortName=%MOZ_APP_DISPLAYNAME% -AppLongName=Mozilla %MOZ_APP_DISPLAYNAME% -WindowCaption=Mozilla %MOZ_APP_DISPLAYNAME% Setup -InstallTo=Install %MOZ_APP_DISPLAYNAME% to -Install=Install -Cancel=Cancel -InstalledSuccessfully=Mozilla %MOZ_APP_DISPLAYNAME% has been installed successfully. -ExtractionError=Archive extraction error: -ThereWereErrors=There were errors during installation: -CreatingUserProfile=Creating user profile. Please wait... -UninstallCaption=Mozilla %MOZ_APP_DISPLAYNAME% Uninstall -FilesWillBeRemoved=All files will be removed from -AreYouSure=Are you sure? -InstallationNotFound=Mozilla %MOZ_APP_DISPLAYNAME% installation not found. -UninstalledSuccessfully=Mozilla %MOZ_APP_DISPLAYNAME% has been uninstalled successfully.
deleted file mode 100644 --- a/b2g/locales/en-US/updater/updater.ini +++ /dev/null @@ -1,8 +0,0 @@ -; This Source Code Form is subject to the terms of the Mozilla Public -; License, v. 2.0. If a copy of the MPL was not distributed with this -; file, You can obtain one at http://mozilla.org/MPL/2.0/. - -; This file is in the UTF-8 encoding -[Strings] -TitleText=%MOZ_APP_DISPLAYNAME% Update -InfoText=%MOZ_APP_DISPLAYNAME% is installing your updates and will start in a few moments…
--- a/b2g/locales/filter.py +++ b/b2g/locales/filter.py @@ -1,35 +1,14 @@ # 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/. def test(mod, path, entity = None): import re - # ignore anything but b2g, which is our local repo checkout name + # ignore anything but b2g and specific overloads from dom and toolkit if mod not in ("netwerk", "dom", "toolkit", "security/manager", - "services/sync", "embedding/android", + "mobile", "b2g"): - return False - - # Ignore Lorentz strings, at least temporarily - if mod == "toolkit" and path == "chrome/mozapps/plugins/plugins.dtd": - if entity.startswith('reloadPlugin.'): return False - if entity.startswith('report.'): return False + return "ignore" - if mod != "b2g": - # we only have exceptions for b2g - return True - if not entity: - return not (re.match(r"b2g-l10n.js", path) or - re.match(r"defines.inc", path)) - if path == "defines.inc": - return entity != "MOZ_LANGPACK_CONTRIBUTORS" - - if path != "chrome/region.properties": - # only region.properties exceptions remain, compare all others - return True - - return not (re.match(r"browser\.search\.order\.[1-9]", entity) or - re.match(r"browser\.contentHandlers\.types\.[0-5]", entity) or - re.match(r"gecko\.handlerService\.schemes\.", entity) or - re.match(r"gecko\.handlerService\.defaultHandlersVersion", entity)) + return "error"
--- a/b2g/locales/jar.mn +++ b/b2g/locales/jar.mn @@ -1,18 +1,13 @@ #filter substitution # 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/. @AB_CD@.jar: -% locale browser @AB_CD@ %locale/@AB_CD@/browser/ - locale/@AB_CD@/browser/about.dtd (%chrome/about.dtd) - locale/@AB_CD@/browser/aboutCertError.dtd (%chrome/aboutCertError.dtd) - locale/@AB_CD@/browser/notification.dtd (%chrome/notification.dtd) - locale/@AB_CD@/browser/webapps.dtd (%chrome/webapps.dtd) - locale/@AB_CD@/browser/phishing.dtd (%chrome/phishing.dtd) +% locale b2g-l10n @AB_CD@ %locale/@AB_CD@/b2g-l10n/ -* locale/@AB_CD@/browser/netError.dtd (%chrome/overrides/netError.dtd) -% override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd -* locale/@AB_CD@/browser/appstrings.properties (%chrome/overrides/appstrings.properties) -% override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties +% override chrome://global/locale/netError.dtd chrome://b2g-l10n/locale/netError.dtd +% override chrome://global/locale/appstrings.properties chrome://b2g-l10n/locale/appstrings.properties +* locale/@AB_CD@/b2g-l10n/netError.dtd (%chrome/overrides/netError.dtd) +* locale/@AB_CD@/b2g-l10n/appstrings.properties (%chrome/overrides/appstrings.properties)
--- a/b2g/locales/l10n.ini +++ b/b2g/locales/l10n.ini @@ -6,9 +6,8 @@ depth = ../.. all = b2g/locales/all-locales [compare] dirs = b2g [includes] toolkit = toolkit/locales/l10n.ini -services_sync = services/sync/locales/l10n.ini
--- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -23,16 +23,22 @@ <menuitem id="context-openlinkintab" label="&openLinkCmdInTab.label;" accesskey="&openLinkCmdInTab.accesskey;" oncommand="gContextMenu.openLinkInTab();"/> <menuitem id="context-openlink" label="&openLinkCmd.label;" accesskey="&openLinkCmd.accesskey;" oncommand="gContextMenu.openLink();"/> +#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING + <menuitem id="context-openlinkprivate" + label="&openLinkInPrivateWindowCmd.label;" + accesskey="&openLinkInPrivateWindowCmd.accesskey;" + oncommand="gContextMenu.openLinkInPrivateWindow();"/> +#endif <menuseparator id="context-sep-open"/> <menuitem id="context-bookmarklink" label="&bookmarkThisLinkCmd.label;" accesskey="&bookmarkThisLinkCmd.accesskey;" oncommand="gContextMenu.bookmarkLink();"/> <menuitem id="context-savelink" label="&saveLinkCmd.label;" accesskey="&saveLinkCmd.accesskey;"
--- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -642,16 +642,17 @@ onclick="BrowserGoHome(event);" aboutHomeOverrideTooltip="&abouthome.pageTitle;"/> <toolbaritem id="social-toolbar-item" class="chromeclass-toolbar-additional" removable="false" title="&socialToolbar.title;" hidden="true" + skipintoolbarset="true" observes="socialActiveBroadcaster"> <toolbarbutton id="social-provider-button" class="toolbarbutton-1" type="menu"> <menupopup id="social-statusarea-popup"> <menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center" observes="socialBroadcaster_userDetails" oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();">
--- a/browser/base/content/nsContextMenu.js +++ b/browser/base/content/nsContextMenu.js @@ -133,17 +133,23 @@ nsContextMenu.prototype = { if (uri && uri.host) { this.linkURI = uri; this.linkURL = this.linkURI.spec; this.onPlainTextLink = true; } } var shouldShow = this.onSaveableLink || isMailtoInternal || this.onPlainTextLink; +#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING + var isWindowPrivate = PrivateBrowsingUtils.isWindowPrivate(window); + this.showItem("context-openlink", shouldShow && !isWindowPrivate); + this.showItem("context-openlinkprivate", shouldShow); +#else this.showItem("context-openlink", shouldShow); +#endif this.showItem("context-openlinkintab", shouldShow); this.showItem("context-openlinkincurrent", this.onPlainTextLink); this.showItem("context-sep-open", shouldShow); }, initNavigationItems: function CM_initNavigationItems() { var shouldShow = !(this.isContentSelected || this.onLink || this.onImage || this.onCanvas || this.onVideo || this.onAudio || @@ -679,16 +685,26 @@ nsContextMenu.prototype = { openLink : function () { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "window", { charset: doc.characterSet, referrerURI: doc.documentURIObject }); }, + // Open linked-to URL in a new private window. + openLinkInPrivateWindow : function () { + var doc = this.target.ownerDocument; + urlSecurityCheck(this.linkURL, doc.nodePrincipal); + openLinkIn(this.linkURL, "window", + { charset: doc.characterSet, + referrerURI: doc.documentURIObject, + private: true }); + }, + // Open linked-to URL in a new tab. openLinkInTab: function() { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "tab", { charset: doc.characterSet, referrerURI: doc.documentURIObject }); },
--- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -45,16 +45,21 @@ MOCHITEST_FILES = \ # test_contextmenu.html is disabled on Linux due to bug 513558 ifneq (gtk2,$(MOZ_WIDGET_TOOLKIT)) MOCHITEST_FILES += \ audio.ogg \ test_contextmenu.html \ subtst_contextmenu.html \ $(NULL) +ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING +MOCHITEST_FILES += \ + privateBrowsingMode.js \ + $(NULL) +endif endif # The following tests are disabled because they are unreliable: # browser_bug423833.js is bug 428712 # browser_sanitize-download-history.js is bug 432425 # # browser_sanitizeDialog_treeView.js is disabled until the tree view is added # back to the clear recent history dialog (sanitize.xul), if it ever is (bug
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/privateBrowsingMode.js @@ -0,0 +1,3 @@ +// This file is only present in per-window private browsing buikds. +var perWindowPrivateBrowsing = true; +
--- a/browser/base/content/test/test_contextmenu.html +++ b/browser/base/content/test/test_contextmenu.html @@ -9,16 +9,18 @@ <body> Browser context menu tests. <p id="display"></p> <div id="content"> </div> <pre id="test"> +<script> var perWindowPrivateBrowsing = false; </script> +<script type="text/javascript" src="privateBrowsingMode.js"></script> <script class="testbody" type="text/javascript"> /** Test for Login Manager: multiple login autocomplete. **/ SpecialPowers.Cu.import("resource://gre/modules/InlineSpellChecker.jsm", window); const Ci = SpecialPowers.Ci; @@ -287,23 +289,34 @@ function runTest(testNum) { ].concat(inspectItems); checkContextMenu(plainTextItems); closeContextMenu(); openContextMenuFor(link); // Invoke context menu for next test. break; case 3: // Context menu for text link - checkContextMenu(["context-openlinkintab", true, - "context-openlink", true, - "---", null, - "context-bookmarklink", true, - "context-savelink", true, - "context-copylink", true - ].concat(inspectItems)); + if (perWindowPrivateBrowsing) { + checkContextMenu(["context-openlinkintab", true, + "context-openlink", true, + "context-openlinkprivate", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copylink", true + ].concat(inspectItems)); + } else { + checkContextMenu(["context-openlinkintab", true, + "context-openlink", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copylink", true + ].concat(inspectItems)); + } closeContextMenu(); openContextMenuFor(mailto); // Invoke context menu for next test. break; case 4: // Context menu for text mailto-link checkContextMenu(["context-copyemail", true].concat(inspectItems)); closeContextMenu(); @@ -745,54 +758,90 @@ function runTest(testNum) { selectText(selecttextlink); // Select text prior to opening context menu. openContextMenuFor(selecttextlink); // Invoke context menu for next test. return; case 25: // Context menu for selected text which matches valid URL pattern if (SpecialPowers.Services.appinfo.OS == "Darwin") { // This test is only enabled on Mac due to bug 736399. - checkContextMenu(["context-openlinkincurrent", true, - "context-openlinkintab", true, - "context-openlink", true, - "---", null, - "context-bookmarklink", true, - "context-savelink", true, - "context-copy", true, - "context-selectall", true, - "---", null, - "context-searchselect", true, - "context-viewpartialsource-selection", true - ].concat(inspectItems)); + if (perWindowPrivateBrowsing) { + checkContextMenu(["context-openlinkincurrent", true, + "context-openlinkintab", true, + "context-openlink", true, + "context-openlinkprivate", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copy", true, + "context-selectall", true, + "---", null, + "context-searchselect", true, + "context-viewpartialsource-selection", true + ].concat(inspectItems)); + } else { + checkContextMenu(["context-openlinkincurrent", true, + "context-openlinkintab", true, + "context-openlink", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copy", true, + "context-selectall", true, + "---", null, + "context-searchselect", true, + "context-viewpartialsource-selection", true + ].concat(inspectItems)); + } } closeContextMenu(); // clear the selection because following tests don't expect any selection subwindow.getSelection().removeAllRanges(); openContextMenuFor(imagelink) break; case 26: // Context menu for image link - checkContextMenu(["context-openlinkintab", true, - "context-openlink", true, - "---", null, - "context-bookmarklink", true, - "context-savelink", true, - "context-copylink", true, - "---", null, - "context-viewimage", true, - "context-copyimage-contents", true, - "context-copyimage", true, - "---", null, - "context-saveimage", true, - "context-sendimage", true, - "context-setDesktopBackground", true, - "context-viewimageinfo", true - ].concat(inspectItems)); + if (perWindowPrivateBrowsing) { + checkContextMenu(["context-openlinkintab", true, + "context-openlink", true, + "context-openlinkprivate", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copylink", true, + "---", null, + "context-viewimage", true, + "context-copyimage-contents", true, + "context-copyimage", true, + "---", null, + "context-saveimage", true, + "context-sendimage", true, + "context-setDesktopBackground", true, + "context-viewimageinfo", true + ].concat(inspectItems)); + } else { + checkContextMenu(["context-openlinkintab", true, + "context-openlink", true, + "---", null, + "context-bookmarklink", true, + "context-savelink", true, + "context-copylink", true, + "---", null, + "context-viewimage", true, + "context-copyimage-contents", true, + "context-copyimage", true, + "---", null, + "context-saveimage", true, + "context-sendimage", true, + "context-setDesktopBackground", true, + "context-viewimageinfo", true + ].concat(inspectItems)); + } closeContextMenu(); selectInputText(select_inputtext); // Select text prior to opening context menu. openContextMenuFor(select_inputtext); // Invoke context menu for next test. return; case 27: // Context menu for selected text in input checkContextMenu(["context-undo", false,
--- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -217,16 +217,17 @@ function openLinkIn(url, where, params) var aCharset = params.charset; var aReferrerURI = params.referrerURI; var aRelatedToCurrent = params.relatedToCurrent; var aInBackground = params.inBackground; var aDisallowInheritPrincipal = params.disallowInheritPrincipal; // Currently, this parameter works only for where=="tab" or "current" var aIsUTF8 = params.isUTF8; var aInitiatingDoc = params.initiatingDoc; + var aIsPrivate = params.private; if (where == "save") { if (!aInitiatingDoc) { Components.utils.reportError("openUILink/openLinkIn was called with " + "where == 'save' but without initiatingDoc. See bug 814264."); return; } saveURL(url, null, null, true, null, aReferrerURI, aInitiatingDoc); @@ -262,18 +263,24 @@ function openLinkIn(url, where, params) allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup; sa.AppendElement(wuri); sa.AppendElement(charset); sa.AppendElement(aReferrerURI); sa.AppendElement(aPostData); sa.AppendElement(allowThirdPartyFixupSupports); - Services.ww.openWindow(w || window, getBrowserURL(), - null, "chrome,dialog=no,all", sa); + let features = "chrome,dialog=no,all"; +#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING + if (aIsPrivate) { + features += ",private"; + } +#endif + + Services.ww.openWindow(w || window, getBrowserURL(), null, features, sa); return; } let loadInBackground = where == "current" ? false : aInBackground; if (loadInBackground == null) { loadInBackground = aFromChrome ? false : getBoolPref("browser.tabs.loadInBackground");
--- a/browser/components/downloads/content/downloads.js +++ b/browser/components/downloads/content/downloads.js @@ -680,18 +680,18 @@ const DownloadsView = { * DownloadsDataItem object for which the view item is requested. * * @return Object that can be used to notify item status events. */ getViewItem: function DV_getViewItem(aDataItem) { // If the item is visible, just return it, otherwise return a mock object // that doesn't react to notifications. - if (aDataItem.downloadId in this._viewItems) { - return this._viewItems[aDataItem.downloadId]; + if (aDataItem.downloadGuid in this._viewItems) { + return this._viewItems[aDataItem.downloadGuid]; } return this._invisibleViewItem; }, /** * Mock DownloadsDataItem object that doesn't react to notifications. */ _invisibleViewItem: Object.freeze({ @@ -702,17 +702,17 @@ const DownloadsView = { /** * Creates a new view item associated with the specified data item, and adds * it to the top or the bottom of the list. */ _addViewItem: function DV_addViewItem(aDataItem, aNewest) { let element = document.createElement("richlistitem"); let viewItem = new DownloadsViewItem(aDataItem, element); - this._viewItems[aDataItem.downloadId] = viewItem; + this._viewItems[aDataItem.downloadGuid] = viewItem; if (aNewest) { this.richListBox.insertBefore(element, this.richListBox.firstChild); } else { this.richListBox.appendChild(element); } }, /** @@ -720,17 +720,17 @@ const DownloadsView = { */ _removeViewItem: function DV_removeViewItem(aDataItem) { let element = this.getViewItem(aDataItem)._element; let previousSelectedIndex = this.richListBox.selectedIndex; this.richListBox.removeChild(element); this.richListBox.selectedIndex = Math.min(previousSelectedIndex, this.richListBox.itemCount - 1); - delete this._viewItems[aDataItem.downloadId]; + delete this._viewItems[aDataItem.downloadGuid]; }, ////////////////////////////////////////////////////////////////////////////// //// User interface event functions /** * Helper function to do commands on a specific download item. * @@ -856,18 +856,18 @@ function DownloadsViewItem(aDataItem, aE // as bug 239948 comment 12 is handled, the "file" property will be always a // file URL rather than a file name. At that point we should remove the "//" // (double slash) from the icon URI specification (see test_moz_icon_uri.js). this.image = "moz-icon://" + this.dataItem.file + "?size=32"; let attributes = { "type": "download", "class": "download-state", - "id": "downloadsItem_" + this.dataItem.downloadId, - "downloadId": this.dataItem.downloadId, + "id": "downloadsItem_" + this.dataItem.downloadGuid, + "downloadGuid": this.dataItem.downloadGuid, "state": this.dataItem.state, "progress": this.dataItem.inProgress ? this.dataItem.percentComplete : 100, "target": this.dataItem.target, "image": this.image }; for (let attributeName in attributes) { this._element.setAttribute(attributeName, attributes[attributeName]); @@ -1165,18 +1165,18 @@ const DownloadsViewController = { //////////////////////////////////////////////////////////////////////////////// //// DownloadsViewItemController /** * Handles all the user interaction events, in particular the "commands", * related to a single item in the downloads list widgets. */ function DownloadsViewItemController(aElement) { - let downloadId = aElement.getAttribute("downloadId"); - this.dataItem = DownloadsCommon.data.dataItems[downloadId]; + let downloadGuid = aElement.getAttribute("downloadGuid"); + this.dataItem = DownloadsCommon.data.dataItems[downloadGuid]; } DownloadsViewItemController.prototype = { ////////////////////////////////////////////////////////////////////////////// //// Constants get kPrefBdmAlertOnExeOpen() "browser.download.manager.alertOnEXEOpen", get kPrefBdmScanWhenDone() "browser.download.manager.scanWhenDone", @@ -1227,34 +1227,32 @@ DownloadsViewItemController.prototype = /** * This object contains one key for each command that operates on this item. * * In commands, the "this" identifier points to the controller item. */ commands: { cmd_delete: function DVIC_cmd_delete() { - this.commands.downloadsCmd_cancel.apply(this); - - Services.downloads.removeDownload(this.dataItem.downloadId); + this.dataItem.getDownload(function (aDownload) { + if (this.dataItem.inProgress) { + aDownload.cancel(); + this._ensureLocalFileRemoved(); + } + aDownload.remove(); + }.bind(this)); }, downloadsCmd_cancel: function DVIC_downloadsCmd_cancel() { if (this.dataItem.inProgress) { - Services.downloads.cancelDownload(this.dataItem.downloadId); - - // It is possible that in some cases the Download Manager service - // doesn't delete the file from disk when canceling. See bug 732924. - try { - let localFile = this.dataItem.localFile; - if (localFile.exists()) { - localFile.remove(false); - } - } catch (ex) { } + this.dataItem.getDownload(function (aDownload) { + aDownload.cancel(); + this._ensureLocalFileRemoved(); + }.bind(this)); } }, downloadsCmd_open: function DVIC_downloadsCmd_open() { // Confirm opening executable files if required. let localFile = this.dataItem.localFile; if (localFile.isExecutable()) { @@ -1290,33 +1288,35 @@ DownloadsViewItemController.prototype = } Services.prefs.setBoolPref(this.kPrefBdmAlertOnExeOpen, !checkbox.value); } } // Actually open the file. - try { - let launched = false; + this.dataItem.getDownload(function (aDownload) { try { - let mimeInfo = this.dataItem.download.MIMEInfo; - if (mimeInfo.preferredAction == mimeInfo.useHelperApp) { - mimeInfo.launchWithFile(localFile); - launched = true; + let launched = false; + try { + let mimeInfo = aDownload.MIMEInfo; + if (mimeInfo.preferredAction == mimeInfo.useHelperApp) { + mimeInfo.launchWithFile(localFile); + launched = true; + } + } catch (ex) { } + if (!launched) { + localFile.launch(); } - } catch (ex) { } - if (!launched) { - localFile.launch(); + } catch (ex) { + // If launch fails, try sending it through the system's external "file:" + // URL handler. + this._openExternal(localFile); } - } catch (ex) { - // If launch fails, try sending it through the system's external "file:" - // URL handler. - this._openExternal(localFile); - } + }.bind(this)); // We explicitly close the panel here to give the user the feedback that // their click has been received, and we're handling the action. // Otherwise, we'd have to wait for the file-type handler to execute // before the panel would close. This also helps to prevent the user from // accidentally opening a file several times. DownloadsPanel.hidePanel(); }, @@ -1349,26 +1349,30 @@ DownloadsViewItemController.prototype = // Otherwise, we'd have to wait for the operating system file manager // window to open before the panel closed. This also helps to prevent the // user from opening the containing folder several times. DownloadsPanel.hidePanel(); }, downloadsCmd_pauseResume: function DVIC_downloadsCmd_pauseResume() { - if (this.dataItem.paused) { - Services.downloads.resumeDownload(this.dataItem.downloadId); - } else { - Services.downloads.pauseDownload(this.dataItem.downloadId); - } + this.dataItem.getDownload(function (aDownload) { + if (this.dataItem.paused) { + aDownload.resume(); + } else { + aDownload.pause(); + } + }.bind(this)); }, downloadsCmd_retry: function DVIC_downloadsCmd_retry() { - Services.downloads.retryDownload(this.dataItem.downloadId); + this.dataItem.getDownload(function (aDownload) { + aDownload.retry(); + }); }, downloadsCmd_openReferrer: function DVIC_downloadsCmd_openReferrer() { openURL(this.dataItem.referrer); }, downloadsCmd_copyLocation: function DVIC_downloadsCmd_copyLocation() @@ -1407,16 +1411,31 @@ DownloadsViewItemController.prototype = /** * Support function to open the specified nsIFile. */ _openExternal: function DVIC_openExternal(aFile) { let protocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"] .getService(Ci.nsIExternalProtocolService); protocolSvc.loadUrl(makeFileURI(aFile)); + }, + + /** + * Support function that deletes the local file for a download. This is + * used in cases where the Download Manager service doesn't delete the file + * from disk when cancelling. See bug 732924. + */ + _ensureLocalFileRemoved: function DVIC_ensureLocalFileRemoved() + { + try { + let localFile = this.dataItem.localFile; + if (localFile.exists()) { + localFile.remove(false); + } + } catch (ex) { } } }; //////////////////////////////////////////////////////////////////////////////// //// DownloadsSummary /**
--- a/browser/components/downloads/src/DownloadsCommon.jsm +++ b/browser/components/downloads/src/DownloadsCommon.jsm @@ -201,82 +201,80 @@ this.DownloadsCommon = { { if (this._summary) { return this._summary; } return this._summary = new DownloadsSummaryData(aNumToExclude); }, /** - * Given an iterable collection of nsIDownload's, generates and returns + * Given an iterable collection of DownloadDataItems, generates and returns * statistics about that collection. * - * @param aDownloads An iterable collection of nsIDownloads. + * @param aDataItems An iterable collection of DownloadDataItems. * * @return Object whose properties are the generated statistics. Currently, * we return the following properties: * * numActive : The total number of downloads. * numPaused : The total number of paused downloads. * numScanning : The total number of downloads being scanned. * numDownloading : The total number of downloads being downloaded. * totalSize : The total size of all downloads once completed. * totalTransferred: The total amount of transferred data for these * downloads. * slowestSpeed : The slowest download rate. * rawTimeLeft : The estimated time left for the downloads to * complete. * percentComplete : The percentage of bytes successfully downloaded. */ - summarizeDownloads: function DC_summarizeDownloads(aDownloads) + summarizeDownloads: function DC_summarizeDownloads(aDataItems) { let summary = { numActive: 0, numPaused: 0, numScanning: 0, numDownloading: 0, totalSize: 0, totalTransferred: 0, // slowestSpeed is Infinity so that we can use Math.min to // find the slowest speed. We'll set this to 0 afterwards if // it's still at Infinity by the time we're done iterating all - // downloads. + // dataItems. slowestSpeed: Infinity, rawTimeLeft: -1, percentComplete: -1 } - // If no download has been loaded, don't use the methods of the Download - // Manager service, so that it is not initialized unnecessarily. - for (let download of aDownloads) { + for (let dataItem of aDataItems) { summary.numActive++; - switch (download.state) { + switch (dataItem.state) { case nsIDM.DOWNLOAD_PAUSED: summary.numPaused++; break; case nsIDM.DOWNLOAD_SCANNING: summary.numScanning++; break; case nsIDM.DOWNLOAD_DOWNLOADING: summary.numDownloading++; - if (download.size > 0 && download.speed > 0) { - let sizeLeft = download.size - download.amountTransferred; + if (dataItem.maxBytes > 0 && dataItem.speed > 0) { + let sizeLeft = dataItem.maxBytes - dataItem.currBytes; summary.rawTimeLeft = Math.max(summary.rawTimeLeft, - sizeLeft / download.speed); + sizeLeft / dataItem.speed); summary.slowestSpeed = Math.min(summary.slowestSpeed, - download.speed); + dataItem.speed); } break; } // Only add to total values if we actually know the download size. - if (download.size > 0 && - download.state != nsIDM.DOWNLOAD_CANCELED && - download.state != nsIDM.DOWNLOAD_FAILED) { - summary.totalSize += download.size; - summary.totalTransferred += download.amountTransferred; + if (dataItem.maxBytes > 0 && + dataItem.state != nsIDM.DOWNLOAD_CANCELED && + dataItem.state != nsIDM.DOWNLOAD_FAILED) { + summary.totalSize += dataItem.maxBytes; + summary.totalTransferred += dataItem.currBytes; } } if (summary.numActive != 0 && summary.totalSize != 0 && summary.numActive != summary.numScanning) { summary.percentComplete = (summary.totalTransferred / summary.totalSize) * 100; } @@ -366,31 +364,31 @@ const DownloadsData = { * this because getService isn't available for us when this method is * called, and we must ensure to register our listeners before the * getService call for the Download Manager returns. */ initializeDataLink: function DD_initializeDataLink(aDownloadManagerService) { // Start receiving real-time events. aDownloadManagerService.addListener(this); - Services.obs.addObserver(this, "download-manager-remove-download", false); + Services.obs.addObserver(this, "download-manager-remove-download-guid", false); Services.obs.addObserver(this, "download-manager-database-type-changed", false); }, /** * Stops receiving events for current downloads and cancels any pending read. */ terminateDataLink: function DD_terminateDataLink() { this._terminateDataAccess(); // Stop receiving real-time events. Services.obs.removeObserver(this, "download-manager-database-type-changed"); - Services.obs.removeObserver(this, "download-manager-remove-download"); + Services.obs.removeObserver(this, "download-manager-remove-download-guid"); Services.downloads.removeListener(this); }, ////////////////////////////////////////////////////////////////////////////// //// Registration of views /** * Array of view objects that should be notified when the available download @@ -432,22 +430,22 @@ const DownloadsData = { * @param aView * DownloadsView object to be initialized. */ _updateView: function DD_updateView(aView) { // Indicate to the view that a batch loading operation is in progress. aView.onDataLoadStarting(); - // Sort backwards by download identifier, ensuring that the most recent + // Sort backwards by start time, ensuring that the most recent // downloads are added first regardless of their state. let loadedItemsArray = [dataItem for each (dataItem in this.dataItems) if (dataItem)]; - loadedItemsArray.sort(function(a, b) b.downloadId - a.downloadId); + loadedItemsArray.sort(function(a, b) b.startTime - a.startTime); loadedItemsArray.forEach( function (dataItem) aView.onDataItemAdded(dataItem, false) ); // Notify the view that all data is available unless loading is in progress. if (!this._pendingStatement) { aView.onDataLoadCompleted(); } @@ -493,40 +491,40 @@ const DownloadsData = { * it's not already in the list, but never updating the returned object using * the data from the database, if the object already exists. * * @param aSource * Object containing the data with which the item should be initialized * if it doesn't already exist in the list. This should implement * either nsIDownload or mozIStorageRow. If the item exists, this * argument is only used to retrieve the download identifier. - * @param aMayReuseId + * @param aMayReuseGUID * If false, indicates that the download should not be added if a * download with the same identifier was removed in the meantime. This * ensures that, while loading the list asynchronously, downloads that * have been removed in the meantime do no reappear inadvertently. * * @return New or existing data item, or null if the item was deleted from the * list of available downloads. */ - _getOrAddDataItem: function DD_getOrAddDataItem(aSource, aMayReuseId) + _getOrAddDataItem: function DD_getOrAddDataItem(aSource, aMayReuseGUID) { - let downloadId = (aSource instanceof Ci.nsIDownload) - ? aSource.id - : aSource.getResultByName("id"); - if (downloadId in this.dataItems) { - let existingItem = this.dataItems[downloadId]; - if (existingItem || !aMayReuseId) { + let downloadGuid = (aSource instanceof Ci.nsIDownload) + ? aSource.guid + : aSource.getResultByName("guid"); + if (downloadGuid in this.dataItems) { + let existingItem = this.dataItems[downloadGuid]; + if (existingItem || !aMayReuseGUID) { // Returns null if the download was removed and we can't reuse the item. return existingItem; } } let dataItem = new DownloadsDataItem(aSource); - this.dataItems[downloadId] = dataItem; + this.dataItems[downloadGuid] = dataItem; // Create the view items before returning. let addToStartOfList = aSource instanceof Ci.nsIDownload; this._views.forEach( function (view) view.onDataItemAdded(dataItem, addToStartOfList) ); return dataItem; }, @@ -607,20 +605,20 @@ const DownloadsData = { } } else { if (this._loadState != this.kLoadAll) { // Load only the relevant columns from the downloads database. The // columns are read in the _initFromDataRow method of DownloadsDataItem. // Order by descending download identifier so that the most recent // downloads are notified first to the listening views. let statement = Services.downloads.DBConnection.createAsyncStatement( - "SELECT id, target, name, source, referrer, state, " + "SELECT guid, target, name, source, referrer, state, " + "startTime, endTime, currBytes, maxBytes " + "FROM moz_downloads " - + "ORDER BY id DESC" + + "ORDER BY startTime DESC" ); try { this._pendingStatement = statement.executeAsync(this); } finally { statement.finalize(); } } } @@ -686,32 +684,37 @@ const DownloadsData = { }, ////////////////////////////////////////////////////////////////////////////// //// nsIObserver observe: function DD_observe(aSubject, aTopic, aData) { switch (aTopic) { - case "download-manager-remove-download": + case "download-manager-remove-download-guid": // If a single download was removed, remove the corresponding data item. if (aSubject) { - this._removeDataItem(aSubject.QueryInterface(Ci.nsISupportsPRUint32)); + this._removeDataItem(aSubject.QueryInterface(Ci.nsISupportsCString) + .data); break; } // Multiple downloads have been removed. Iterate over known downloads // and remove those that don't exist anymore. for each (let dataItem in this.dataItems) { if (dataItem) { - try { - Services.downloads.getDownload(dataItem.downloadId); - } catch (ex) { - this._removeDataItem(dataItem.downloadId); - } + // Bug 449811 - We have to bind to the dataItem because Javascript + // doesn't do fresh let-bindings per loop iteration. + let dataItemBinding = dataItem; + Services.downloads.getDownloadByGUID(dataItemBinding.downloadGuid, + function(aStatus, aResult) { + if (aStatus == Components.results.NS_ERROR_NOT_AVAILABLE) { + this._removeDataItem(dataItemBinding.downloadGuid); + } + }.bind(this)); } } break; case "download-manager-database-type-changed": let pbs = Cc["@mozilla.org/privatebrowsing;1"] .getService(Ci.nsIPrivateBrowsingService); if (pbs.privateBrowsingEnabled) { @@ -753,25 +756,21 @@ const DownloadsData = { dataItem.startTime = Math.round(aDownload.startTime / 1000); dataItem.currBytes = aDownload.amountTransferred; dataItem.maxBytes = aDownload.size; // When a download is retried, we create a different download object from // the database with the same ID as before. This means that the nsIDownload // that the dataItem holds might now need updating. // - // It's possible, however, that dataItem.download is still a lazy getter - // if we never read the download property after initializing the dataItem - // from a data row in the downloads database. In that case, we can leave - // it alone - the next time the download property is accessed, the right - // download object will be retrieved. - let downloadIsGetter = Object.getOwnPropertyDescriptor(dataItem, "download") - .value === undefined; - if (!downloadIsGetter) { - dataItem.download = aDownload; + // We only overwrite this in the event that _download exists, because if it + // doesn't, that means that no caller ever tried to get the nsIDownload, + // which means it was never retrieved and doesn't need to be overwritten. + if (dataItem._download) { + dataItem._download = aDownload; } this._views.forEach( function (view) view.getViewItem(dataItem).onStateChange() ); if (isNew && !dataItem.newDownloadNotified) { dataItem.newDownloadNotified = true; @@ -879,20 +878,20 @@ DownloadsDataItem.prototype = { * * The endTime property is initialized to the current date and time. * * @param aDownload * The nsIDownload with the current state. */ _initFromDownload: function DDI_initFromDownload(aDownload) { - this.download = aDownload; + this._download = aDownload; // Fetch all the download properties eagerly. - this.downloadId = aDownload.id; + this.downloadGuid = aDownload.guid; this.file = aDownload.target.spec; this.target = aDownload.displayName; this.uri = aDownload.source.spec; this.referrer = aDownload.referrer && aDownload.referrer.spec; this.state = aDownload.state; this.startTime = Math.round(aDownload.startTime / 1000); this.endTime = Date.now(); this.currBytes = aDownload.amountTransferred; @@ -912,52 +911,83 @@ DownloadsDataItem.prototype = { * be avoided unless the object is really required. * * @param aStorageRow * The mozIStorageRow from the downloads database. */ _initFromDataRow: function DDI_initFromDataRow(aStorageRow) { // Get the download properties from the data row. - this.downloadId = aStorageRow.getResultByName("id"); + this._download = null; + this.downloadGuid = aStorageRow.getResultByName("guid"); this.file = aStorageRow.getResultByName("target"); this.target = aStorageRow.getResultByName("name"); this.uri = aStorageRow.getResultByName("source"); this.referrer = aStorageRow.getResultByName("referrer"); this.state = aStorageRow.getResultByName("state"); this.startTime = Math.round(aStorageRow.getResultByName("startTime") / 1000); this.endTime = Math.round(aStorageRow.getResultByName("endTime") / 1000); this.currBytes = aStorageRow.getResultByName("currBytes"); this.maxBytes = aStorageRow.getResultByName("maxBytes"); - // Allows accessing the underlying download object lazily. - XPCOMUtils.defineLazyGetter(this, "download", function () - Services.downloads.getDownload(this.downloadId)); - // Now we have to determine if the download is resumable, but don't want to // access the underlying download object unnecessarily. The only case where // the property is relevant is when we are currently downloading data, and // in this case the download object is already loaded in memory or will be // loaded very soon in any case. In all the other cases, including a paused // download, we assume that the download is resumable. The property will be // updated as soon as the underlying download state changes. + + // We'll start by assuming we're resumable, and then if we're downloading, + // update resumable property in case we were wrong. + this.resumable = true; + if (this.state == nsIDM.DOWNLOAD_DOWNLOADING) { - this.resumable = this.download.resumable; - } else { - this.resumable = true; + this.getDownload(function(aDownload) { + this.resumable = aDownload.resumable; + }.bind(this)); } // Compute the other properties without accessing the download object. this.speed = 0; this.percentComplete = this.maxBytes <= 0 ? -1 : Math.round(this.currBytes / this.maxBytes * 100); }, /** + * Asynchronous getter for the download object corresponding to this data item. + * + * @param aCallback + * A callback function which will be called when the download object is + * available. It should accept one argument which will be the download + * object. + */ + getDownload: function DDI_getDownload(aCallback) { + if (this._download) { + // Return the download object asynchronously to the caller + let download = this._download; + Services.tm.mainThread.dispatch(function () aCallback(download), + Ci.nsIThread.DISPATCH_NORMAL); + } else { + Services.downloads.getDownloadByGUID(this.downloadGuid, + function(aStatus, aResult) { + if (!Components.isSuccessCode(aStatus)) { + Cu.reportError( + new Components.Exception("Cannot retrieve download for GUID: " + + this.downloadGuid)); + } else { + this._download = aResult; + aCallback(aResult); + } + }.bind(this)); + } + }, + + /** * Indicates whether the download is proceeding normally, and not finished * yet. This includes paused downloads. When this property is true, the * "progress" property represents the current progress of the download. */ get inProgress() { return [ nsIDM.DOWNLOAD_NOTSTARTED, @@ -1447,40 +1477,37 @@ const DownloadsIndicatorData = { * Last number of seconds estimated until all in-progress downloads with a * known size and speed will finish. This value is stored to allow smoothing * in case of small variations. This is set to -1 if the previous value is * unknown. */ _lastTimeLeft: -1, /** - * A generator function for the downloads that this summary is currently + * A generator function for the dataItems that this summary is currently * interested in. This generator is passed off to summarizeDownloads in order - * to generate statistics about the downloads we care about - in this case, - * it's all active downloads. + * to generate statistics about the dataItems we care about - in this case, + * it's all dataItems for active downloads. */ - _activeDownloads: function DID_activeDownloads() + _activeDataItems: function DID_activeDataItems() { - // If no download has been loaded, don't use the methods of the Download - // Manager service, so that it is not initialized unnecessarily. - if (this._itemCount > 0) { - let downloads = Services.downloads.activeDownloads; - while (downloads.hasMoreElements()) { - yield downloads.getNext().QueryInterface(Ci.nsIDownload); + for each (let dataItem in DownloadsCommon.data.dataItems) { + if (dataItem && dataItem.inProgress) { + yield dataItem; } } }, /** * Computes aggregate values based on the current state of downloads. */ _refreshProperties: function DID_refreshProperties() { let summary = - DownloadsCommon.summarizeDownloads(this._activeDownloads()); + DownloadsCommon.summarizeDownloads(this._activeDataItems()); // Determine if the indicator should be shown or get attention. this._hasDownloads = (this._itemCount > 0); // If all downloads are paused, show the progress indicator as paused. this._paused = summary.numActive > 0 && summary.numActive == summary.numPaused; @@ -1558,17 +1585,17 @@ DownloadsSummaryData.prototype = { * @param aView * DownloadsSummary view to be removed. */ removeView: function DSD_removeView(aView) { DownloadsViewPrototype.removeView.call(this, aView); if (this._views.length == 0) { - // Clear out our collection of DownloadsDataItems. If we ever have + // Clear out our collection of DownloadDataItems. If we ever have // another view registered with us, this will get re-populated. this._dataItems = []; } }, ////////////////////////////////////////////////////////////////////////////// //// Callback functions from DownloadsData - see the documentation in //// DownloadsViewPrototype for more information on what these functions @@ -1651,39 +1678,39 @@ DownloadsSummaryData.prototype = { aView.description = this._description; aView.details = this._details; }, ////////////////////////////////////////////////////////////////////////////// //// Property updating based on current download status /** - * A generator function for the downloads that this summary is currently + * A generator function for the dataItems that this summary is currently * interested in. This generator is passed off to summarizeDownloads in order - * to generate statistics about the downloads we care about - in this case, - * it's the downloads in this._dataItems after the first few to exclude, + * to generate statistics about the dataItems we care about - in this case, + * it's the dataItems in this._dataItems after the first few to exclude, * which was set when constructing this DownloadsSummaryData instance. */ - _downloadsForSummary: function DSD_downloadsForSummary() + _dataItemsForSummary: function DSD_dataItemsForSummary() { if (this._dataItems.length > 0) { for (let i = this._numToExclude; i < this._dataItems.length; ++i) { - yield this._dataItems[i].download; + yield this._dataItems[i]; } } }, /** * Computes aggregate values based on the current state of downloads. */ _refreshProperties: function DSD_refreshProperties() { // Pre-load summary with default values. let summary = - DownloadsCommon.summarizeDownloads(this._downloadsForSummary()); + DownloadsCommon.summarizeDownloads(this._dataItemsForSummary()); this._description = DownloadsCommon.strings .otherDownloads(summary.numActive); this._percentComplete = summary.percentComplete; // If all downloads are paused, show the progress indicator as paused. this._showingProgress = summary.numDownloading > 0 || summary.numPaused > 0;
--- a/browser/components/downloads/test/browser/head.js +++ b/browser/components/downloads/test/browser/head.js @@ -167,17 +167,17 @@ function gen_resetState() function gen_addDownloadRows(aDataRows) { let columnNames = Object.keys(gDownloadRowTemplate).join(", "); let parameterNames = Object.keys(gDownloadRowTemplate) .map(function(n) ":" + n) .join(", "); let statement = Services.downloads.DBConnection.createAsyncStatement( "INSERT INTO moz_downloads (" + columnNames + - ") VALUES(" + parameterNames + ")"); + ", guid) VALUES(" + parameterNames + ", GENERATE_GUID())"); try { // Execute the statement for each of the provided downloads in reverse. for (let i = aDataRows.length - 1; i >= 0; i--) { let dataRow = aDataRows[i]; // Populate insert parameters from the provided data. for (let columnName in gDownloadRowTemplate) { if (!(columnName in dataRow)) { @@ -188,27 +188,29 @@ function gen_addDownloadRows(aDataRows) statement.params[columnName] = dataRow[columnName]; } // Run the statement asynchronously and wait. statement.executeAsync({ handleResult: function(aResultSet) { }, handleError: function(aError) { - Cu.reportError(aError); + Cu.reportError(aError.message + " (Result = " + aError.result + ")"); }, handleCompletion: function(aReason) { testRunner.continueTest(); } }); yield; - // At each iteration, ensure that the end time in the global template is - // distinct, as this column is used to sort each download in its category. + // At each iteration, ensure that the start and end time in the global + // template is distinct, as these column are used to sort each download + // in its category. + gDownloadRowTemplate.startTime++; gDownloadRowTemplate.endTime++; } } finally { statement.finalize(); } } function gen_openPanel(aData)
--- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -440,24 +440,24 @@ BrowserGlue.prototype = { // been warned about them yet, open the plugins update page. if (Services.prefs.getBoolPref(PREF_PLUGINS_NOTIFYUSER)) this._showPluginUpdatePage(); // For any add-ons that were installed disabled and can be enabled offer // them to the user. let changedIDs = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_INSTALLED); if (changedIDs.length > 0) { - let browser = this.getMostRecentBrowserWindow().gBrowser; + let win = this.getMostRecentBrowserWindow(); AddonManager.getAddonsByIDs(changedIDs, function(aAddons) { aAddons.forEach(function(aAddon) { // If the add-on isn't user disabled or can't be enabled then skip it. if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE)) return; - browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id); + win.openUILinkIn("about:newaddon?id=" + aAddon.id, "tab"); }) }); } let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL"); Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet); // Perform default browser checking. @@ -712,34 +712,33 @@ BrowserGlue.prototype = { // We haven't shown the notification before, so do so now. return true; }, _showRightsNotification: function BG__showRightsNotification() { // Stick the notification onto the selected tab of the active browser window. var win = this.getMostRecentBrowserWindow(); - var browser = win.gBrowser; // for closure in notification bar callback - var notifyBox = browser.getNotificationBox(); + var notifyBox = win.gBrowser.getNotificationBox(); var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); var rightsBundle = Services.strings.createBundle("chrome://global/locale/aboutRights.properties"); var buttonLabel = rightsBundle.GetStringFromName("buttonLabel"); var buttonAccessKey = rightsBundle.GetStringFromName("buttonAccessKey"); var productName = brandBundle.GetStringFromName("brandFullName"); var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1); var buttons = [ { label: buttonLabel, accessKey: buttonAccessKey, popup: null, callback: function(aNotificationBar, aButton) { - browser.selectedTab = browser.addTab("about:rights"); + win.openUILinkIn("about:rights", "tab"); } } ]; // Set pref to indicate we've shown the notification. var currentVersion = Services.prefs.getIntPref("browser.rights.version"); Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true); @@ -794,26 +793,25 @@ BrowserGlue.prototype = { let url = getNotifyString({propName: "notificationURL", prefName: "startup.homepage_override_url"}); let label = getNotifyString({propName: "notificationButtonLabel", stringName: "pu.notifyButton.label"}); let key = getNotifyString({propName: "notificationButtonAccessKey", stringName: "pu.notifyButton.accesskey"}); let win = this.getMostRecentBrowserWindow(); - let browser = win.gBrowser; // for closure in notification bar callback - let notifyBox = browser.getNotificationBox(); + let notifyBox = win.gBrowser.getNotificationBox(); let buttons = [ { label: label, accessKey: key, popup: null, callback: function(aNotificationBar, aButton) { - browser.selectedTab = browser.addTab(url); + win.openUILinkIn(url, "tab"); } } ]; let notification = notifyBox.appendNotification(text, "post-update-notification", null, notifyBox.PRIORITY_INFO_LOW, buttons); notification.persistence = -1; // Until user closes it @@ -842,18 +840,17 @@ BrowserGlue.prototype = { prefName: "startup.homepage_override_url"}); var self = this; function clickCallback(subject, topic, data) { // This callback will be called twice but only once with this topic if (topic != "alertclickcallback") return; let win = self.getMostRecentBrowserWindow(); - let browser = win.gBrowser; - browser.selectedTab = browser.addTab(data); + win.openUILinkIn(data, "tab"); } try { // This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot // be displayed per the idl. notifier.showAlertNotification(null, title, text, true, url, clickCallback); } @@ -921,17 +918,17 @@ BrowserGlue.prototype = { Services.prefs.setBoolPref(PREF_TELEMETRY_NOTIFIED_OPTOUT, true); let notification = appendTelemetryNotification(telemetryPrompt, null, false); let link = appendLearnMoreLink(notification); link.addEventListener('click', function() { // Open the learn more url in a new tab let url = Services.urlFormatter.formatURLPref("app.support.baseURL"); url += "how-can-i-help-submitting-performance-data"; - tabbrowser.selectedTab = tabbrowser.addTab(url); + win.openUILinkIn(url, "tab"); // Remove the notification on which the user clicked notification.parentNode.removeNotification(notification, true); }, false); return; } var telemetryPrompted = null; try { @@ -968,17 +965,17 @@ BrowserGlue.prototype = { // Set pref to indicate we've shown the notification. Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV); let notification = appendTelemetryNotification(telemetryPrompt, buttons, true); let link = appendLearnMoreLink(notification); link.addEventListener('click', function() { // Open the learn more url in a new tab - tabbrowser.selectedTab = tabbrowser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL)); + win.openUILinkIn(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL), "tab"); // Remove the notification on which the user clicked notification.parentNode.removeNotification(notification, true); // Add a new notification to that tab, with no "Learn more" link notifyBox = tabbrowser.getNotificationBox(); appendTelemetryNotification(telemetryPrompt, buttons, true); }, false); }, #endif @@ -986,18 +983,17 @@ BrowserGlue.prototype = { _showPluginUpdatePage: function BG__showPluginUpdatePage() { Services.prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false); var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"]. getService(Ci.nsIURLFormatter); var updateUrl = formatter.formatURLPref(PREF_PLUGINS_UPDATEURL); var win = this.getMostRecentBrowserWindow(); - var browser = win.gBrowser; - browser.selectedTab = browser.addTab(updateUrl); + win.openUILinkIn(updateUrl, "tab"); }, /** * Initialize Places * - imports the bookmarks html file if bookmarks database is empty, try to * restore bookmarks from a JSON backup if the backend indicates that the * database was corrupt. * @@ -1218,30 +1214,30 @@ BrowserGlue.prototype = { var accessKey = placesBundle.GetStringFromName("lockPromptInfoButton.accessKey"); var helpTopic = "places-locked"; var url = Cc["@mozilla.org/toolkit/URLFormatterService;1"]. getService(Components.interfaces.nsIURLFormatter). formatURLPref("app.support.baseURL"); url += helpTopic; - var browser = this.getMostRecentBrowserWindow().gBrowser; + var win = this.getMostRecentBrowserWindow(); var buttons = [ { label: buttonText, accessKey: accessKey, popup: null, callback: function(aNotificationBar, aButton) { - browser.selectedTab = browser.addTab(url); + win.openUILinkIn(url, "tab"); } } ]; - var notifyBox = browser.getNotificationBox(); + var notifyBox = win.gBrowser.getNotificationBox(); var notification = notifyBox.appendNotification(text, title, null, notifyBox.PRIORITY_CRITICAL_MEDIUM, buttons); notification.persistence = -1; // Until user closes it }, _migrateUI: function BG__migrateUI() { const UI_VERSION = 8;
--- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -49,17 +49,16 @@ #endif [xpcom] @BINPATH@/dependentlibs.list #ifdef XP_WIN32 @BINPATH@/@DLL_PREFIX@gkmedias@DLL_SUFFIX@ #endif @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@ -@BINPATH@/@DLL_PREFIX@soundtouch@DLL_SUFFIX@ #ifdef MOZ_SHARED_MOZGLUE @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@ #endif #ifndef MOZ_STATIC_JS @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@ #endif #ifndef MOZ_NATIVE_NSPR @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
--- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -353,16 +353,18 @@ These should match what Safari and other <!ENTITY searchFocusUnix.commandkey "j"> <!ENTITY tabView.commandkey "e"> <!ENTITY openLinkCmdInTab.label "Open Link in New Tab"> <!ENTITY openLinkCmdInTab.accesskey "T"> <!ENTITY openLinkCmd.label "Open Link in New Window"> <!ENTITY openLinkCmd.accesskey "W"> +<!ENTITY openLinkInPrivateWindowCmd.label "Open Link in New Private Window"> +<!ENTITY openLinkInPrivateWindowCmd.accesskey "P"> <!ENTITY openLinkCmdInCurrent.label "Open Link"> <!ENTITY openLinkCmdInCurrent.accesskey "O"> <!ENTITY openFrameCmdInTab.label "Open Frame in New Tab"> <!ENTITY openFrameCmdInTab.accesskey "T"> <!ENTITY openFrameCmd.label "Open Frame in New Window"> <!ENTITY openFrameCmd.accesskey "W"> <!ENTITY showOnlyThisFrameCmd.label "Show Only This Frame"> <!ENTITY showOnlyThisFrameCmd.accesskey "S">
--- a/client.mk +++ b/client.mk @@ -274,16 +274,17 @@ EXTRA_CONFIG_DEPS := \ @$(PYTHON) $(TOPSRCDIR)/js/src/config/check-sync-dirs.py $(TOPSRCDIR)/js/src/build $(TOPSRCDIR)/build @echo Generating $@ using autoconf cd $(@D); $(AUTOCONF) CONFIG_STATUS_DEPS := \ $(wildcard $(TOPSRCDIR)/*/confvars.sh) \ $(CONFIGURES) \ $(TOPSRCDIR)/allmakefiles.sh \ + $(TOPSRCDIR)/CLOBBER \ $(TOPSRCDIR)/nsprpub/configure \ $(TOPSRCDIR)/config/milestone.txt \ $(TOPSRCDIR)/js/src/config/milestone.txt \ $(TOPSRCDIR)/browser/config/version.txt \ $(TOPSRCDIR)/build/virtualenv/packages.txt \ $(TOPSRCDIR)/build/virtualenv/populate_virtualenv.py \ $(NULL)
--- a/config/writemozinfo.py +++ b/config/writemozinfo.py @@ -34,16 +34,20 @@ def build_dict(env=os.environ): d["os"] = known_os[o] else: # Allow unknown values, just lowercase them. d["os"] = o.lower() # Widget toolkit, just pass the value directly through. d["toolkit"] = env["MOZ_WIDGET_TOOLKIT"] + # Application name + if 'MOZ_APP_NAME' in env: + d["appname"] = env["MOZ_APP_NAME"] + # processor p = env["TARGET_CPU"] # for universal mac builds, put in a special value if d["os"] == "mac" and "UNIVERSAL_BINARY" in env and env["UNIVERSAL_BINARY"] == "1": p = "universal-x86-x86_64" else: # do some slight massaging for some values #TODO: retain specific values in case someone wants them?
--- a/configure.in +++ b/configure.in @@ -118,16 +118,32 @@ then *** EOF exit 1 break fi fi MOZ_BUILD_ROOT=`pwd` +dnl Do not allow building if a clobber is required +dnl ============================================================== +dnl TODO Make this better, ideally this would clobber automaticially +if test -e $_objdir/CLOBBER; then + if test $_topsrcdir/CLOBBER -nt $_objdir/CLOBBER; then + echo " ***" + echo " * CLOBBER has been modified indicating a clobber is required:" + cat $_topsrcdir/CLOBBER | sed '/^#/d' | sed 's/^/ * /' + echo " ***" + exit 1 + break; + fi +else + touch $_objdir/CLOBBER +fi + MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python2.6 python2.5 python) if test -z "$PYTHON"; then AC_MSG_ERROR([python was not found in \$PATH]) fi AC_MSG_RESULT([Creating Python environment]) dnl This verifies our Python version is sane and ensures the Python dnl virtualenv is present and up to date. It sanitizes the environment @@ -724,16 +740,28 @@ EOF "$_WINDRES_MINOR_VERSION" -lt "$WINDRES_MINOR_VERSION" -o \ "$_WINDRES_MAJOR_VERSION" -eq "$WINDRES_MAJOR_VERSION" -a \ "$_WINDRES_MINOR_VERSION" -eq "$WINDRES_MINOR_VERSION" -a \ "$_WINDRES_RELEASE_VERSION" -lt "$WINDRES_RELEASE_VERSION" then AC_MSG_ERROR([windres version $WINDRES_VERSION or higher is required to build.]) fi + AC_CHECK_PROGS(MIDL, $target-widl widl) + if test -n "$MIDL"; then + case "$target" in + i*86-*) + MIDL_FLAGS="$MIDL_FLAGS --win32 -m32" + ;; + x86_64-*) + MIDL_FLAGS="$MIDL_FLAGS --win64 -m64" + ;; + esac + fi + MOZ_WINSDK_MAXVER=0x06020000 fi # !GNU_CC AC_DEFINE_UNQUOTED(WINVER,0x$WINVER) AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER) # Require OS features provided by IE 6.0 SP2 (XP SP2) AC_DEFINE_UNQUOTED(_WIN32_IE,0x0603) @@ -5161,16 +5189,26 @@ AC_DEFINE(IBMBIDI) dnl ======================================================== dnl accessibility support on by default on all platforms dnl ======================================================== MOZ_ARG_DISABLE_BOOL(accessibility, [ --disable-accessibility Disable accessibility support], ACCESSIBILITY=, ACCESSIBILITY=1 ) if test "$ACCESSIBILITY"; then + case "$target" in + *-mingw*) + if test -z "$MIDL"; then + if test "$GCC" != "yes"; then + AC_MSG_ERROR([MIDL could not be found. Building accessibility without MIDL is not supported.]) + else + AC_MSG_ERROR([You have accessibility enabled, but widl could not be found. Add --disable-accessibility to your mozconfig or install widl. See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details.]) + fi + fi + esac AC_DEFINE(ACCESSIBILITY) fi dnl ======================================================== dnl Disable printing dnl ======================================================== MOZ_ARG_DISABLE_BOOL(printing, [ --disable-printing Disable printing support], @@ -5553,25 +5591,16 @@ fi if test -n "$MOZ_SPEEX_RESAMPLER"; then AC_DEFINE(MOZ_SPEEX_RESAMPLER) fi if test -n "$MOZ_SOUNDTOUCH"; then AC_DEFINE(MOZ_SOUNDTOUCH) fi -if test -z "$GNU_CC" -a "$OS_ARCH" = "WINNT"; then - SOUNDTOUCH_LIBS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)soundtouch.$(LIB_SUFFIX)' -else - SOUNDTOUCH_LIBS='-lsoundtouch' -fi -AC_SUBST(SOUNDTOUCH_CFLAGS) -AC_SUBST(SOUNDTOUCH_LIBS) -AC_SUBST(SOUNDTOUCH_CONFIG) - if test -n "$MOZ_CUBEB"; then case "$target" in *-android*|*-linuxandroid*) if test -n "$gonkdir"; then AC_DEFINE(MOZ_CUBEB) fi dnl No Android implementation of libcubeb yet. ;; @@ -8904,16 +8933,17 @@ fi # Generate a JSON config file for unittest harnesses etc to read # build configuration details from in a standardized way. OS_TARGET=${OS_TARGET} \ TARGET_CPU=${TARGET_CPU} \ MOZ_DEBUG=${MOZ_DEBUG} \ MOZ_WIDGET_TOOLKIT=${MOZ_WIDGET_TOOLKIT} \ UNIVERSAL_BINARY=${UNIVERSAL_BINARY} \ MOZ_CRASHREPORTER=${MOZ_CRASHREPORTER} \ +MOZ_APP_NAME=${MOZ_APP_NAME} \ MOZ_PER_WINDOW_PRIVATE_BROWSING=${MOZ_PER_WINDOW_PRIVATE_BROWSING} \ $PYTHON ${_topsrcdir}/config/writemozinfo.py ./mozinfo.json.tmp if cmp -s ./mozinfo.json.tmp ./mozinfo.json; then rm ./mozinfo.json.tmp else mv -f ./mozinfo.json.tmp ./mozinfo.json fi
--- a/content/base/public/Element.h +++ b/content/base/public/Element.h @@ -525,17 +525,17 @@ public: { GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId); } void SetId(const nsAString& aId) { SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true); } - nsDOMTokenList* ClassList(); + nsDOMTokenList* GetClassList(); nsDOMAttributeMap* GetAttributes() { nsDOMSlots *slots = DOMSlots(); if (!slots->mAttributeMap) { slots->mAttributeMap = new nsDOMAttributeMap(this); } return slots->mAttributeMap;
--- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -44,16 +44,28 @@ class nsIPresShell; class nsIPrincipal; class nsIURI; class nsNodeSupportsWeakRefTearoff; class nsNodeWeakReference; class nsXPCClassInfo; namespace mozilla { namespace dom { +/** + * @return true if aChar is what the DOM spec defines as 'space character'. + * http://dom.spec.whatwg.org/#space-character + */ +inline bool IsSpaceCharacter(PRUnichar aChar) { + return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || + aChar == '\f'; +} +inline bool IsSpaceCharacter(char aChar) { + return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || + aChar == '\f'; +} class Element; class EventHandlerNonNull; class OnErrorEventHandlerNonNull; template<typename T> class Optional; } // namespace dom } // namespace mozilla namespace JS {
--- a/content/base/src/Element.cpp +++ b/content/base/src/Element.cpp @@ -442,34 +442,34 @@ Element::GetLastElementChild() const return child->AsElement(); } } return nullptr; } nsDOMTokenList* -Element::ClassList() +Element::GetClassList() { Element::nsDOMSlots *slots = DOMSlots(); if (!slots->mClassList) { - nsCOMPtr<nsIAtom> classAttr = GetClassAttributeName(); + nsIAtom* classAttr = GetClassAttributeName(); if (classAttr) { slots->mClassList = new nsDOMTokenList(this, classAttr); } } return slots->mClassList; } void Element::GetClassList(nsIDOMDOMTokenList** aClassList) { - NS_IF_ADDREF(*aClassList = ClassList()); + NS_IF_ADDREF(*aClassList = GetClassList()); } already_AddRefed<nsIHTMLCollection> Element::GetElementsByTagName(const nsAString& aLocalName) { return NS_GetContentList(this, kNameSpaceID_Unknown, aLocalName); }
--- a/content/base/src/Link.cpp +++ b/content/base/src/Link.cpp @@ -85,25 +85,25 @@ Link::LinkState() const if (!mRegistered && mLinkState == eLinkState_Unknown) { // First, make sure the href attribute has a valid link (bug 23209). nsCOMPtr<nsIURI> hrefURI(GetURI()); if (!hrefURI) { self->mLinkState = eLinkState_NotLink; return nsEventStates(); } + // Assume that we are not visited until we are told otherwise. + self->mLinkState = eLinkState_Unvisited; + // We have a good href, so register with History. if (mHistory) { nsresult rv = mHistory->RegisterVisitedCallback(hrefURI, self); if (NS_SUCCEEDED(rv)) { self->mRegistered = true; - // Assume that we are not visited until we are told otherwise. - self->mLinkState = eLinkState_Unvisited; - // And make sure we are in the document's link map. nsIDocument *doc = element->GetCurrentDoc(); if (doc) { doc->AddStyleRelevantLink(self); } } } }
--- a/content/base/src/nsContentList.h +++ b/content/base/src/nsContentList.h @@ -255,17 +255,17 @@ public: void* aData, bool aDeep = true, nsIAtom* aMatchAtom = nullptr, int32_t aMatchNameSpaceId = kNameSpaceID_None, bool aFuncMayDependOnAttr = true); virtual ~nsContentList(); // nsWrapperCache - using nsWrapperCache::GetWrapper; + using nsWrapperCache::GetWrapperPreserveColor; virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap); // nsIDOMHTMLCollection NS_DECL_NSIDOMHTMLCOLLECTION // nsBaseContentList overrides virtual int32_t IndexOf(nsIContent *aContent, bool aDoFlush);
--- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -839,29 +839,30 @@ nsGenericDOMDataNode::AppendText(const P bool aNotify) { return SetTextInternal(mText.GetLength(), 0, aBuffer, aLength, aNotify); } bool nsGenericDOMDataNode::TextIsOnlyWhitespace() { + // FIXME: should this method take content language into account? if (mText.Is2b()) { // The fragment contains non-8bit characters and such characters // are never considered whitespace. return false; } const char* cp = mText.Get1b(); const char* end = cp + mText.GetLength(); while (cp < end) { char ch = *cp; - if (!XP_IS_SPACE(ch)) { + if (!dom::IsSpaceCharacter(ch)) { return false; } ++cp; } return true; }
--- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -1827,30 +1827,31 @@ nsObjectLoadingContent::LoadObject(bool NS_ASSERTION(!mFrameLoader && !mInstanceOwner, "switched to type null but also loaded something"); if (mChannel) { // If we were loading with a channel but then failed over, throw it away CloseChannel(); } + // Don't try to initialize final listener below + finalListener = nullptr; + // Don't notify, as LoadFallback doesn't know of our previous state // (so really this is just setting mFallbackType) LoadFallback(fallbackType, false); } // Notify of our final state NotifyStateChanged(oldType, oldState, false, aNotify); // // Pass load on to finalListener if loading with a channel // - // If we re-entered and loaded something else, that load will have cleaned up - // our our listener. if (!mIsLoading) { LOG(("OBJLC [%p]: Re-entered before dispatching to final listener", this)); } else if (finalListener) { NS_ASSERTION(mType != eType_Null && mType != eType_Loading, "We should not have a final listener with a non-loaded type"); // Note that we always enter into LoadObject() from ::OnStartRequest when // loading with a channel. mSrcStreamLoading = true; @@ -1865,16 +1866,17 @@ nsObjectLoadingContent::LoadObject(bool // transition, we can just Unload and call LoadFallback (which will notify // again) mType = eType_Null; // This could *also* technically re-enter if OnStartRequest fails after // spawning a plugin. mIsLoading = true; UnloadObject(false); NS_ENSURE_TRUE(mIsLoading, NS_OK); + CloseChannel(); LoadFallback(fallbackType, true); } } return NS_OK; } // This call can re-enter when dealing with plugin listeners
--- a/content/base/src/nsTextFragment.h +++ b/content/base/src/nsTextFragment.h @@ -19,32 +19,16 @@ class nsString; class nsCString; // XXX should this normalize the code to keep a \u0000 at the end? // XXX nsTextFragmentPool? -// XXX these need I18N spankage -#define XP_IS_SPACE(_ch) \ - (((_ch) == ' ') || ((_ch) == '\t') || ((_ch) == '\n') || ((_ch) == '\r')) - -#define XP_IS_UPPERCASE(_ch) \ - (((_ch) >= 'A') && ((_ch) <= 'Z')) - -#define XP_IS_LOWERCASE(_ch) \ - (((_ch) >= 'a') && ((_ch) <= 'z')) - -#define XP_TO_LOWER(_ch) ((_ch) | 32) - -#define XP_TO_UPPER(_ch) ((_ch) & ~32) - -#define XP_IS_SPACE_W XP_IS_SPACE - /** * A fragment of text. If mIs2b is 1 then the m2b pointer is valid * otherwise the m1b pointer is valid. If m1b is used then each byte * of data represents a single ucs2 character with the high byte being * zero. * * This class does not have a virtual destructor therefore it is not * meant to be subclassed.
--- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -871,24 +871,23 @@ WebGLContext::GetCanvasLayer(nsDisplayLi canvasLayer->Updated(); mResetLayer = false; return canvasLayer.forget().get(); } void -WebGLContext::GetContextAttributes(dom::WebGLContextAttributes &result) +WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializer> &retval) { + retval.SetNull(); if (!IsContextStable()) - { - // XXXbz spec says we should still return our attributes in - // this case! Should we store them all in mOptions? return; - } + + dom::WebGLContextAttributes& result = retval.SetValue(); gl::ContextFormat cf = gl->ActualFormat(); result.alpha = cf.alpha > 0; result.depth = cf.depth > 0; result.stencil = cf.stencil > 0; result.antialias = cf.samples > 1; result.premultipliedAlpha = mOptions.premultipliedAlpha; result.preserveDrawingBuffer = mOptions.preserveDrawingBuffer;
--- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -78,16 +78,17 @@ class WebGLMemoryPressureObserver; class WebGLRectangleObject; class WebGLContextBoundObject; class WebGLActiveInfo; class WebGLShaderPrecisionFormat; class WebGLExtensionBase; namespace dom { struct WebGLContextAttributes; +struct WebGLContextAttributesInitializer; } enum FakeBlackStatus { DoNotNeedFakeBlack, DoNeedFakeBlack, DontKnowIfNeedFakeBlack }; struct VertexAttrib0Status { enum { Default, EmulatedUninitializedArray, EmulatedInitializedArray }; }; @@ -393,17 +394,17 @@ public: return mWidth; } WebGLsizei DrawingBufferHeight() const { if (!IsContextStable()) return 0; return mHeight; } - void GetContextAttributes(dom::WebGLContextAttributes& retval); + void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributesInitializer>& retval); bool IsContextLost() const { return !IsContextStable(); } void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval); JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv); void ActiveTexture(WebGLenum texture); void AttachShader(WebGLProgram* program, WebGLShader* shader); void BindAttribLocation(WebGLProgram* program, WebGLuint location, const nsAString& name); void BindBuffer(WebGLenum target, WebGLBuffer* buf);
--- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -20,16 +20,17 @@ #include "VideoFrameContainer.h" #include "mozilla/CORSMode.h" #include "nsDOMMediaStream.h" #include "mozilla/Mutex.h" #include "nsTimeRanges.h" #include "nsIDOMWakeLock.h" #include "AudioChannelCommon.h" #include "DecoderTraits.h" +#include "MediaMetadataManager.h" // Define to output information on decoding and painting framerate /* #define DEBUG_FRAME_RATE 1 */ typedef uint16_t nsMediaNetworkState; typedef uint16_t nsMediaReadyState; namespace mozilla { @@ -114,18 +115,18 @@ public: * Call this to reevaluate whether we should start/stop due to our owner * document being active or inactive. */ void NotifyOwnerDocumentActivityChanged(); // Called by the video decoder object, on the main thread, // when it has read the metadata containing video dimensions, // etc. - virtual void MetadataLoaded(uint32_t aChannels, - uint32_t aRate, + virtual void MetadataLoaded(int aChannels, + int aRate, bool aHasAudio, const MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE; // Called by the video decoder object, on the main thread, // when it has read the first frame of the video // aResourceFullyLoaded should be true if the resource has been // fully loaded and the caller will call ResourceLoaded next. virtual void FirstFrameLoaded(bool aResourceFullyLoaded) MOZ_FINAL MOZ_OVERRIDE;
--- a/content/html/content/public/nsIHTMLCollection.h +++ b/content/html/content/public/nsIHTMLCollection.h @@ -65,21 +65,21 @@ public: { JSObject* namedItem = NamedItem(cx, name, error); found = !!namedItem; return namedItem; } virtual void GetSupportedNames(nsTArray<nsString>& aNames) = 0; - JSObject* GetWrapper() + JSObject* GetWrapperPreserveColor() { nsWrapperCache* cache; CallQueryInterface(this, &cache); - return cache->GetWrapper(); + return cache->GetWrapperPreserveColor(); } virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLCollection, NS_IHTMLCOLLECTION_IID) #endif /* nsIHTMLCollection_h___ */
--- a/content/html/content/src/HTMLPropertiesCollection.h +++ b/content/html/content/src/HTMLPropertiesCollection.h @@ -53,17 +53,17 @@ class HTMLPropertiesCollection : public public nsWrapperCache { friend class PropertyNodeList; friend class PropertyStringList; public: HTMLPropertiesCollection(nsGenericHTMLElement* aRoot); virtual ~HTMLPropertiesCollection(); - using nsWrapperCache::GetWrapper; + using nsWrapperCache::GetWrapperPreserveColor; virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap); virtual Element* GetElementAt(uint32_t aIndex); NS_IMETHOD NamedItem(const nsAString& aName, nsIDOMNode** aResult); void SetDocument(nsIDocument* aDocument); nsINode* GetParentObject();
--- a/content/html/content/src/nsHTMLAudioElement.cpp +++ b/content/html/content/src/nsHTMLAudioElement.cpp @@ -119,16 +119,17 @@ nsHTMLAudioElement::MozSetup(uint32_t aC if (NS_FAILED(rv)) { mAudioStream->Shutdown(); mAudioStream = nullptr; return rv; } MetadataLoaded(aChannels, aRate, true, nullptr); mAudioStream->SetVolume(mVolume); + return NS_OK; } NS_IMETHODIMP nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, uint32_t* aRetVal) { if (!mAudioStream) { return NS_ERROR_DOM_INVALID_STATE_ERR;
--- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -60,16 +60,17 @@ #include "nsIDOMNotifyAudioAvailableEvent.h" #include "nsMediaFragmentURIParser.h" #include "nsURIHashKey.h" #include "nsJSUtils.h" #include "MediaStreamGraph.h" #include "nsDOMMediaStream.h" #include "nsIScriptError.h" #include "nsHostObjectProtocolHandler.h" +#include "MediaMetadataManager.h" #include "nsCSSParser.h" #include "nsIMediaList.h" #include "ImageContainer.h" #include "nsIPowerManagerService.h" #ifdef MOZ_OGG @@ -2178,17 +2179,18 @@ nsresult nsHTMLMediaElement::InitializeD if (!decoder->Init(this)) { LOG(PR_LOG_DEBUG, ("%p Failed to init cloned decoder %p", this, decoder.get())); return NS_ERROR_FAILURE; } double duration = aOriginal->GetDuration(); if (duration >= 0) { decoder->SetDuration(duration); - decoder->SetSeekable(aOriginal->IsSeekable()); + decoder->SetTransportSeekable(aOriginal->IsTransportSeekable()); + decoder->SetMediaSeekable(aOriginal->IsMediaSeekable()); } MediaResource* resource = originalResource->CloneData(decoder); if (!resource) { LOG(PR_LOG_DEBUG, ("%p Failed to cloned stream for decoder %p", this, decoder.get())); return NS_ERROR_FAILURE; } @@ -2507,29 +2509,29 @@ void nsHTMLMediaElement::ProcessMediaFra } } if (start > 0.0) { SetCurrentTime(start); mFragmentStart = start; } } -void nsHTMLMediaElement::MetadataLoaded(uint32_t aChannels, - uint32_t aRate, +void nsHTMLMediaElement::MetadataLoaded(int aChannels, + int aRate, bool aHasAudio, const MetadataTags* aTags) { mChannels = aChannels; mRate = aRate; mHasAudio = aHasAudio; mTags = aTags; ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); DispatchAsyncEvent(NS_LITERAL_STRING("durationchange")); DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata")); - if (mDecoder && mDecoder->IsSeekable()) { + if (mDecoder && mDecoder->IsTransportSeekable() && mDecoder->IsMediaSeekable()) { ProcessMediaFragmentURI(); mDecoder->SetFragmentEndTime(mFragmentEnd); } } void nsHTMLMediaElement::FirstFrameLoaded(bool aResourceFullyLoaded) { ChangeReadyState(aResourceFullyLoaded ?
--- a/content/html/content/test/reflect.js +++ b/content/html/content/test/reflect.js @@ -43,19 +43,19 @@ function reflectString(aParameters) is(element[idlAttr], "", "When not set, the IDL attribute should return the empty string"); /** * TODO: as long as null stringification doesn't follow the WebIDL * specifications, don't add it to the loop below and keep it here. */ element.setAttribute(contentAttr, null); - todo_is(element.getAttribute(contentAttr), "null", + is(element.getAttribute(contentAttr), "null", "null should have been stringified to 'null'"); - todo_is(element[idlAttr], "null", + is(element[idlAttr], "null", "null should have been stringified to 'null'"); element.removeAttribute(contentAttr); element[idlAttr] = null; // TODO: remove this ugly hack when null stringification will work as expected. if (element.localName == "textarea" && idlAttr == "wrap") { is(element.getAttribute(contentAttr), "null", "null should have been stringified to 'null'"); @@ -418,24 +418,18 @@ function reflectBoolean(aParameters) result: true }, { value: { }, stringified: "[object Object]", result: true }, ]; valuesToTest.forEach(function(v) { element.setAttribute(contentAttr, v.value); is(element[idlAttr], true, "IDL attribute should return always return 'true' if the content attribute has been set"); - if (v.value === null) { - // bug 667856 - todo(element.getAttribute(contentAttr), v.stringified, - "Content attribute should return the stringified value it has been set to."); - } else { - is(element.getAttribute(contentAttr), v.stringified, - "Content attribute should return the stringified value it has been set to."); - } + is(element.getAttribute(contentAttr), v.stringified, + "Content attribute should return the stringified value it has been set to."); element.removeAttribute(contentAttr); element[idlAttr] = v.value; is(element[idlAttr], v.result, "IDL attribute should return " + v.result); is(element.getAttribute(contentAttr), v.result ? "" : null, v.result ? "Content attribute should return the empty string." : "Content attribute should return null."); is(element.hasAttribute(contentAttr), v.result, @@ -460,17 +454,17 @@ function reflectBoolean(aParameters) * - attribute String name of the attribute * - nonNegative Boolean true if the attribute is limited to 'non-negative numbers', false otherwise * - defaultValue Integer [optional] default value, if one exists */ function reflectInt(aParameters) { // Expected value returned by .getAttribute() when |value| has been previously passed to .setAttribute(). function expectedGetAttributeResult(value) { - return (value !== null) ? String(value) : ""; + return String(value); } function stringToInteger(value, nonNegative, defaultValue) { // Parse: Ignore leading whitespace, find [+/-][numbers] var result = /^[ \t\n\f\r]*([\+\-]?[0-9]+)/.exec(value); if (result) { if ((nonNegative ? 0:-0x80000000) <= result[1] && result[1] <= 0x7FFFFFFF) { // If the value is within allowed value range for signed/unsigned integer, return value
--- a/content/media/AbstractMediaDecoder.h +++ b/content/media/AbstractMediaDecoder.h @@ -3,27 +3,32 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef AbstractMediaDecoder_h_ #define AbstractMediaDecoder_h_ #include "nsISupports.h" +#include "nsDataHashtable.h" +#include "nsThreadUtils.h" namespace mozilla { namespace layers { class ImageContainer; } class MediaResource; class ReentrantMonitor; class VideoFrameContainer; +class TimedMetadata; + +typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags; /** * The AbstractMediaDecoder class describes the public interface for a media decoder * and is used by the MediaReader classes. */ class AbstractMediaDecoder : public nsISupports { public: @@ -56,22 +61,34 @@ public: virtual int64_t GetEndMediaTime() const = 0; // Return the duration of the media in microseconds. virtual int64_t GetMediaDuration() = 0; // Set the duration of the media in microseconds. virtual void SetMediaDuration(int64_t aDuration) = 0; + // Set the media as being seekable or not. + virtual void SetMediaSeekable(bool aMediaSeekable) = 0; + + // Set the transport level as being seekable or not. + virtual void SetTransportSeekable(bool aTransportSeekable) = 0; + virtual VideoFrameContainer* GetVideoFrameContainer() = 0; virtual mozilla::layers::ImageContainer* GetImageContainer() = 0; - // Return true if seeking is supported. + // Return true if the media layer supports seeking. + virtual bool IsTransportSeekable() = 0; + + // Return true if the transport layer supports seeking. virtual bool IsMediaSeekable() = 0; + virtual void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) = 0; + virtual void QueueMetadata(int64_t aTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) = 0; + // Set the media end time in microseconds virtual void SetMediaEndTime(int64_t aTime) = 0; // Make the decoder state machine update the playback position. Called by // the reader on the decoder thread (Assertions for this checked by // mDecoderStateMachine). This must be called with the decode monitor // held. virtual void UpdatePlaybackPosition(int64_t aTime) = 0; @@ -92,12 +109,38 @@ public: } private: AbstractMediaDecoder* mDecoder; uint32_t& mParsed; uint32_t& mDecoded; }; }; +class AudioMetadataEventRunner : public nsRunnable +{ + private: + nsRefPtr<AbstractMediaDecoder> mDecoder; + public: + AudioMetadataEventRunner(AbstractMediaDecoder* aDecoder, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) + : mDecoder(aDecoder), + mChannels(aChannels), + mRate(aRate), + mHasAudio(aHasAudio), + mTags(aTags) + {} + + NS_IMETHOD Run() + { + mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio, mTags); + return NS_OK; + } + + int mChannels; + int mRate; + bool mHasAudio; + MetadataTags* mTags; +}; + + } #endif
--- a/content/media/Makefile.in +++ b/content/media/Makefile.in @@ -32,16 +32,17 @@ EXPORTS = \ MediaCache.h \ SharedBuffer.h \ StreamBuffer.h \ TimeVarying.h \ VideoFrameContainer.h \ VideoUtils.h \ VideoSegment.h \ VorbisUtils.h \ + MediaMetadataManager.h \ $(NULL) CPPSRCS = \ AudioSegment.cpp \ DecoderTraits.cpp \ FileBlockCache.cpp \ MediaResource.cpp \ MediaStreamGraph.cpp \
--- a/content/media/MediaCache.cpp +++ b/content/media/MediaCache.cpp @@ -756,17 +756,17 @@ MediaCache::FindReusableBlock(TimeStamp continue; } AppendMostReusableBlock(&stream->mMetadataBlocks, &candidates, length); AppendMostReusableBlock(&stream->mPlayedBlocks, &candidates, length); // Don't consider readahead blocks in non-seekable streams. If we // remove the block we won't be able to seek back to read it later. - if (stream->mIsSeekable) { + if (stream->mIsTransportSeekable) { AppendMostReusableBlock(&stream->mReadaheadBlocks, &candidates, length); } } TimeDuration latestUse; int32_t latestUseBlock = -1; for (uint32_t i = 0; i < candidates.Length(); ++i) { TimeDuration nextUse = PredictNextUse(aNow, candidates[i]); @@ -1077,17 +1077,17 @@ MediaCache::Update() Truncate(); // Count the blocks allocated for readahead of non-seekable streams // (these blocks can't be freed but we don't want them to monopolize the // cache) int32_t nonSeekableReadaheadBlockCount = 0; for (uint32_t i = 0; i < mStreams.Length(); ++i) { MediaCacheStream* stream = mStreams[i]; - if (!stream->mIsSeekable) { + if (!stream->mIsTransportSeekable) { nonSeekableReadaheadBlockCount += stream->mReadaheadBlocks.GetCount(); } } // If freeBlockCount is zero, then compute the latest of // the predicted next-uses for all blocks TimeDuration latestNextUse; if (freeBlockCount == 0) { @@ -1105,17 +1105,17 @@ MediaCache::Update() continue; // Figure out where we should be reading from. It's the first // uncached byte after the current mStreamOffset. int64_t dataOffset = stream->GetCachedDataEndInternal(stream->mStreamOffset); // Compute where we'd actually seek to to read at readOffset int64_t desiredOffset = dataOffset; - if (stream->mIsSeekable) { + if (stream->mIsTransportSeekable) { if (desiredOffset > stream->mChannelOffset && desiredOffset <= stream->mChannelOffset + SEEK_VS_READ_THRESHOLD) { // Assume it's more efficient to just keep reading up to the // desired position instead of trying to seek desiredOffset = stream->mChannelOffset; } } else { // We can't seek directly to the desired offset... @@ -1157,17 +1157,17 @@ MediaCache::Update() // We're reading to try to catch up to where the current stream // reader wants to be. Better not stop. LOG(PR_LOG_DEBUG, ("Stream %p catching up", stream)); enableReading = true; } else if (desiredOffset < stream->mStreamOffset + BLOCK_SIZE) { // The stream reader is waiting for us, or nearly so. Better feed it. LOG(PR_LOG_DEBUG, ("Stream %p feeding reader", stream)); enableReading = true; - } else if (!stream->mIsSeekable && + } else if (!stream->mIsTransportSeekable && nonSeekableReadaheadBlockCount >= maxBlocks*NONSEEKABLE_READAHEAD_MAX) { // This stream is not seekable and there are already too many blocks // being cached for readahead for nonseekable streams (which we can't // free). So stop reading ahead now. LOG(PR_LOG_DEBUG, ("Stream %p throttling non-seekable readahead", stream)); enableReading = false; } else if (mIndex.Length() > uint32_t(maxBlocks)) { // We're in the process of bringing the cache size back to the @@ -1204,17 +1204,17 @@ MediaCache::Update() stream, desiredOffset/BLOCK_SIZE, other)); break; } } } if (stream->mChannelOffset != desiredOffset && enableReading) { // We need to seek now. - NS_ASSERTION(stream->mIsSeekable || desiredOffset == 0, + NS_ASSERTION(stream->mIsTransportSeekable || desiredOffset == 0, "Trying to seek in a non-seekable stream!"); // Round seek offset down to the start of the block. This is essential // because we don't want to think we have part of a block already // in mPartialBlockBuffer. stream->mChannelOffset = (desiredOffset/BLOCK_SIZE)*BLOCK_SIZE; actions[i] = stream->mCacheSuspended ? SEEK_AND_RESUME : SEEK; } else if (enableReading && stream->mCacheSuspended) { actions[i] = RESUME; @@ -1770,32 +1770,32 @@ MediaCacheStream::~MediaCacheStream() if (gMediaCache) { NS_ASSERTION(mClosed, "Stream was not closed"); gMediaCache->ReleaseStream(this); MediaCache::MaybeShutdown(); } } void -MediaCacheStream::SetSeekable(bool aIsSeekable) +MediaCacheStream::SetTransportSeekable(bool aIsTransportSeekable) { ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); - NS_ASSERTION(mIsSeekable || aIsSeekable || + NS_ASSERTION(mIsTransportSeekable || aIsTransportSeekable || mChannelOffset == 0, "channel offset must be zero when we become non-seekable"); - mIsSeekable = aIsSeekable; + mIsTransportSeekable = aIsTransportSeekable; // Queue an Update since we may change our strategy for dealing // with this stream gMediaCache->QueueUpdate(); } bool -MediaCacheStream::IsSeekable() +MediaCacheStream::IsTransportSeekable() { ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); - return mIsSeekable; + return mIsTransportSeekable; } bool MediaCacheStream::AreAllStreamsForResourceSuspended(MediaResource** aActiveStream) { ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); MediaCache::ResourceStreamIterator iter(mResourceID); while (MediaCacheStream* stream = iter.Next()) { @@ -2223,17 +2223,17 @@ MediaCacheStream::InitAsClone(MediaCache return rv; mResourceID = aOriginal->mResourceID; // Grab cache blocks from aOriginal as readahead blocks for our stream ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); mPrincipal = aOriginal->mPrincipal; mStreamLength = aOriginal->mStreamLength; - mIsSeekable = aOriginal->mIsSeekable; + mIsTransportSeekable = aOriginal->mIsTransportSeekable; // Cloned streams are initially suspended, since there is no channel open // initially for a clone. mCacheSuspended = true; mChannelEnded = true; if (aOriginal->mDidNotifyDataEnded) { mNotifyDataEndedStatus = aOriginal->mNotifyDataEndedStatus;
--- a/content/media/MediaCache.h +++ b/content/media/MediaCache.h @@ -191,17 +191,17 @@ public: // aClient provides the underlying transport that cache will use to read // data for this stream. MediaCacheStream(ChannelMediaResource* aClient) : mClient(aClient), mInitialized(false), mHasHadUpdate(false), mClosed(false), mDidNotifyDataEnded(false), mResourceID(0), - mIsSeekable(false), mCacheSuspended(false), + mIsTransportSeekable(false), mCacheSuspended(false), mChannelEnded(false), mChannelOffset(0), mStreamLength(-1), mStreamOffset(0), mPlaybackBytesPerSecond(10000), mPinCount(0), mCurrentMode(MODE_PLAYBACK), mMetadataInPartialBlockBuffer(false) {} ~MediaCacheStream(); // Set up this stream with the cache. Can fail on OOM. One @@ -217,17 +217,17 @@ public: // These are called on the main thread. // Tell us whether the stream is seekable or not. Non-seekable streams // will always pass 0 for aOffset to CacheClientSeek. This should only // be called while the stream is at channel offset 0. Seekability can // change during the lifetime of the MediaCacheStream --- every time // we do an HTTP load the seekability may be different (and sometimes // is, in practice, due to the effects of caching proxies). - void SetSeekable(bool aIsSeekable); + void SetTransportSeekable(bool aIsTransportSeekable); // This must be called (and return) before the ChannelMediaResource // used to create this MediaCacheStream is deleted. void Close(); // This returns true when the stream has been closed bool IsClosed() const { return mClosed; } // Returns true when this stream is can be shared by a new resource load bool IsAvailableForSharing() const { @@ -318,18 +318,18 @@ public: bool IsDataCachedToEndOfStream(int64_t aOffset); // The mode is initially MODE_PLAYBACK. void SetReadMode(ReadMode aMode); // This is the client's estimate of the playback rate assuming // the media plays continuously. The cache can't guess this itself // because it doesn't know when the decoder was paused, buffering, etc. // Do not pass zero. void SetPlaybackRate(uint32_t aBytesPerSecond); - // Returns the last set value of SetSeekable. - bool IsSeekable(); + // Returns the last set value of SetTransportSeekable. + bool IsTransportSeekable(); // Returns true when all streams for this resource are suspended or their // channel has ended. // If aActiveResource is non-null, fills it with a pointer to a stream // for this resource that is not suspended or ended. bool AreAllStreamsForResourceSuspended(MediaResource** aActiveResource); // These methods must be called on a different thread from the main @@ -442,17 +442,17 @@ private: // only on the main thread, thus can be read either on the main thread // or while holding the cache's monitor. // This is a unique ID representing the resource we're loading. // All streams with the same mResourceID are loading the same // underlying resource and should share data. int64_t mResourceID; // The last reported seekability state for the underlying channel - bool mIsSeekable; + bool mIsTransportSeekable; // True if the cache has suspended our channel because the cache is // full and the priority of the data that would be received is lower // than the priority of the data already in the cache bool mCacheSuspended; // True if the channel ended and we haven't seeked it again. bool mChannelEnded; // The offset where the next data from the channel will arrive int64_t mChannelOffset;
--- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -298,17 +298,18 @@ bool MediaDecoder::IsInfinite() MediaDecoder::MediaDecoder() : mDecoderPosition(0), mPlaybackPosition(0), mCurrentTime(0.0), mInitialVolume(0.0), mRequestedSeekTime(-1.0), mDuration(-1), - mSeekable(true), + mTransportSeekable(true), + mMediaSeekable(true), mReentrantMonitor("media.decoder"), mPlayState(PLAY_STATE_PAUSED), mNextState(PLAY_STATE_PAUSED), mResourceLoaded(false), mIgnoreProgressData(false), mInfiniteStream(false), mTriggerPlaybackEndedWhenSourceStreamFinishes(false), mOwner(nullptr), @@ -430,17 +431,18 @@ nsresult MediaDecoder::InitializeStateMa MediaDecoder* cloneDonor = static_cast<MediaDecoder*>(aCloneDonor); if (NS_FAILED(mDecoderStateMachine->Init(cloneDonor ? cloneDonor->mDecoderStateMachine : nullptr))) { LOG(PR_LOG_DEBUG, ("%p Failed to init state machine!", this)); return NS_ERROR_FAILURE; } { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - mDecoderStateMachine->SetSeekable(mSeekable); + mDecoderStateMachine->SetTransportSeekable(mTransportSeekable); + mDecoderStateMachine->SetMediaSeekable(mMediaSeekable); mDecoderStateMachine->SetDuration(mDuration); mDecoderStateMachine->SetVolume(mInitialVolume); mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured); if (mFrameBufferLength > 0) { // The valid mFrameBufferLength value was specified earlier mDecoderStateMachine->SetFrameBufferLength(mFrameBufferLength); } @@ -626,20 +628,29 @@ void MediaDecoder::AudioAvailable(float* nsAutoArrayPtr<float> frameBuffer(aFrameBuffer); MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown || !mOwner) { return; } mOwner->NotifyAudioAvailable(frameBuffer.forget(), aFrameBufferLength, aTime); } -void MediaDecoder::MetadataLoaded(uint32_t aChannels, - uint32_t aRate, - bool aHasAudio, - const MetadataTags* aTags) +void MediaDecoder::QueueMetadata(int64_t aPublishTime, + int aChannels, + int aRate, + bool aHasAudio, + MetadataTags* aTags) +{ + NS_ASSERTION(mDecoderStateMachine->OnDecodeThread(), + "Should be on decode thread."); + GetReentrantMonitor().AssertCurrentThreadIn(); + mDecoderStateMachine->QueueMetadata(aPublishTime, aChannels, aRate, aHasAudio, aTags); +} + +void MediaDecoder::MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) { MOZ_ASSERT(NS_IsMainThread()); if (mShuttingDown) { return; } { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); @@ -1180,56 +1191,71 @@ void MediaDecoder::SetDuration(double aD UpdatePlaybackRate(); } void MediaDecoder::SetMediaDuration(int64_t aDuration) { GetStateMachine()->SetDuration(aDuration); } -void MediaDecoder::SetSeekable(bool aSeekable) -{ - MOZ_ASSERT(NS_IsMainThread()); - mSeekable = aSeekable; +void MediaDecoder::SetMediaSeekable(bool aMediaSeekable) { + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + MOZ_ASSERT(NS_IsMainThread() || OnDecodeThread()); + mMediaSeekable = aMediaSeekable; if (mDecoderStateMachine) { - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - mDecoderStateMachine->SetSeekable(aSeekable); + mDecoderStateMachine->SetMediaSeekable(aMediaSeekable); } } -bool MediaDecoder::IsSeekable() +void MediaDecoder::SetTransportSeekable(bool aTransportSeekable) { MOZ_ASSERT(NS_IsMainThread()); - return mSeekable; + mTransportSeekable = aTransportSeekable; + if (mDecoderStateMachine) { + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + mDecoderStateMachine->SetTransportSeekable(aTransportSeekable); + } +} + +bool MediaDecoder::IsTransportSeekable() +{ + MOZ_ASSERT(NS_IsMainThread()); + return mTransportSeekable; } bool MediaDecoder::IsMediaSeekable() { - return GetStateMachine()->IsSeekable(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + MOZ_ASSERT(OnDecodeThread() || NS_IsMainThread()); + return mMediaSeekable; } nsresult MediaDecoder::GetSeekable(nsTimeRanges* aSeekable) { //TODO : change 0.0 to GetInitialTime() when available double initialTime = 0.0; - if (IsSeekable()) { + // We can seek in buffered range if the media is seekable. Also, we can seek + // in unbuffered ranges if the transport level is seekable (local file or the + // server supports range requests, etc.) + if (!IsMediaSeekable()) { + return NS_OK; + } else if (!IsTransportSeekable()){ + if (mDecoderStateMachine && + mDecoderStateMachine->IsSeekableInBufferedRanges()) { + return GetBuffered(aSeekable); + } else { + return NS_OK; + } + } else { double end = IsInfinite() ? std::numeric_limits<double>::infinity() : initialTime + GetDuration(); aSeekable->Add(initialTime, end); return NS_OK; } - - if (mDecoderStateMachine && mDecoderStateMachine->IsSeekableInBufferedRanges()) { - return GetBuffered(aSeekable); - } else { - // The stream is not seekable using only buffered ranges, and is not - // seekable. Don't allow seeking (return no ranges in |seekable|). - return NS_OK; - } } void MediaDecoder::SetFragmentEndTime(double aTime) { MOZ_ASSERT(NS_IsMainThread()); if (mDecoderStateMachine) { ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); mDecoderStateMachine->SetFragmentEndTime(static_cast<int64_t>(aTime * USECS_PER_S));
--- a/content/media/MediaDecoder.h +++ b/content/media/MediaDecoder.h @@ -499,21 +499,24 @@ public: // Set the duration of the media resource in units of seconds. // This is called via a channel listener if it can pick up the duration // from a content header. Must be called from the main thread only. virtual void SetDuration(double aDuration); void SetMediaDuration(int64_t aDuration) MOZ_FINAL MOZ_OVERRIDE; // Set a flag indicating whether seeking is supported - virtual void SetSeekable(bool aSeekable); - - // Return true if seeking is supported. - virtual bool IsSeekable(); - bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE; + virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_FINAL MOZ_OVERRIDE; + virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_FINAL MOZ_OVERRIDE; + // Returns true if this media supports seeking. False for example for WebM + // files without an index and chained ogg files. + virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE; + // Returns true if seeking is supported on a transport level (e.g. the server + // supports range requests, we are playing a file, etc.). + virtual bool IsTransportSeekable(); // Return the time ranges that can be seeked into. virtual nsresult GetSeekable(nsTimeRanges* aSeekable); // Set the end time of the media resource. When playback reaches // this point the media pauses. aTime is in seconds. virtual void SetFragmentEndTime(double aTime); @@ -628,36 +631,42 @@ public: // the reader on the decoder thread (Assertions for this checked by // mDecoderStateMachine). This must be called with the decode monitor // held. void UpdatePlaybackPosition(int64_t aTime) MOZ_FINAL MOZ_OVERRIDE; void SetAudioChannelType(AudioChannelType aType) { mAudioChannelType = aType; } AudioChannelType GetAudioChannelType() { return mAudioChannelType; } + // Send a new set of metadata to the state machine, to be dispatched to the + // main thread to be presented when the |currentTime| of the media is greater + // or equal to aPublishTime. + void QueueMetadata(int64_t aPublishTime, + int aChannels, + int aRate, + bool aHasAudio, + MetadataTags* aTags); + /****** * The following methods must only be called on the main * thread. ******/ // Change to a new play state. This updates the mState variable and // notifies any thread blocking on this object's monitor of the // change. Call on the main thread only. void ChangeState(PlayState aState); // Called when the metadata from the media file has been read by the reader. // Call on the decode thread only. void OnReadMetadataCompleted() MOZ_OVERRIDE { } // Called when the metadata from the media file has been loaded by the // state machine. Call on the main thread only. - void MetadataLoaded(uint32_t aChannels, - uint32_t aRate, - bool aHasAudio, - const MetadataTags* aTags); + void MetadataLoaded(int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags); // Called when the first frame has been loaded. // Call on the main thread only. void FirstFrameLoaded(); // Called when the video has completed playing. // Call on the main thread only. void PlaybackEnded(); @@ -897,19 +906,22 @@ public: // Duration of the media resource. Set to -1 if unknown. // Set when the metadata is loaded. Accessed on the main thread // only. int64_t mDuration; // True when playback should start with audio captured (not playing). bool mInitialAudioCaptured; - // True if the media resource is seekable (server supports byte range - // requests). - bool mSeekable; + // True if the resource is seekable at a transport level (server supports byte + // range requests, local file, etc.). + bool mTransportSeekable; + + // True if the media is seekable (i.e. supports random access). + bool mMediaSeekable; /****** * The following member variables can be accessed from any thread. ******/ // The state machine object for handling the decoding. It is safe to // call methods of this object from other threads. Its internal data // is synchronised on a monitor. The lifetime of this object is
--- a/content/media/MediaDecoderOwner.h +++ b/content/media/MediaDecoderOwner.h @@ -1,24 +1,23 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* 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 MediaDecoderOwner_h_ #define MediaDecoderOwner_h_ +#include "AbstractMediaDecoder.h" class nsHTMLMediaElement; namespace mozilla { class VideoFrameContainer; -typedef nsDataHashtable<nsCStringHashKey, nsCString> MetadataTags; - class MediaDecoderOwner { public: // Called by the media decoder to indicate that the download has stalled // (no data has arrived for a while). virtual void DownloadStalled() = 0; // Dispatch a synchronous event to the decoder owner @@ -49,18 +48,18 @@ public: * Called when data has been written to the underlying audio stream. */ virtual void NotifyAudioAvailable(float* aFrameBuffer, uint32_t aFrameBufferLength, float aTime) = 0; // Called by the video decoder object, on the main thread, // when it has read the metadata containing video dimensions, // etc. - virtual void MetadataLoaded(uint32_t aChannels, - uint32_t aRate, + virtual void MetadataLoaded(int aChannels, + int aRate, bool aHasAudio, const MetadataTags* aTags) = 0; // Called by the video decoder object, on the main thread, // when it has read the first frame of the video // aResourceFullyLoaded should be true if the resource has been // fully loaded and the caller will call ResourceLoaded next. virtual void FirstFrameLoaded(bool aResourceFullyLoaded) = 0;
--- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -12,16 +12,17 @@ #include "mozilla/mozalloc.h" #include "VideoUtils.h" #include "nsTimeRanges.h" #include "nsDeque.h" #include "AudioSegment.h" #include "VideoSegment.h" #include "ImageContainer.h" +#include "prenv.h" #include "mozilla/Preferences.h" #include "mozilla/StandardInteger.h" #include "mozilla/Util.h" namespace mozilla { using namespace layers; using namespace mozilla::dom; @@ -108,44 +109,16 @@ PR_STATIC_ASSERT(QUICK_BUFFERING_LOW_DAT static TimeDuration UsecsToDuration(int64_t aUsecs) { return TimeDuration::FromMilliseconds(static_cast<double>(aUsecs) / USECS_PER_MS); } static int64_t DurationToUsecs(TimeDuration aDuration) { return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S); } -class nsAudioMetadataEventRunner : public nsRunnable -{ -private: - nsRefPtr<MediaDecoder> mDecoder; -public: - nsAudioMetadataEventRunner(MediaDecoder* aDecoder, uint32_t aChannels, - uint32_t aRate, bool aHasAudio, - MetadataTags* aTags) : - mDecoder(aDecoder), - mChannels(aChannels), - mRate(aRate), - mHasAudio(aHasAudio), - mTags(aTags) - { - } - - NS_IMETHOD Run() - { - mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio, mTags); - return NS_OK; - } - - const uint32_t mChannels; - const uint32_t mRate; - const bool mHasAudio; - MetadataTags* mTags; -}; - // Owns the global state machine thread and counts of // state machine and decoder threads. There should // only be one instance of this class. class StateMachineTracker { private: StateMachineTracker() : mMonitor("media.statemachinetracker"), @@ -389,17 +362,18 @@ MediaDecoderStateMachine::MediaDecoderSt mAudioStartTime(-1), mAudioEndTime(-1), mVideoFrameEndTime(-1), mVolume(1.0), mPlaybackRate(1.0), mPreservesPitch(true), mBasePosition(0), mAudioCaptured(false), - mSeekable(true), + mTransportSeekable(true), + mMediaSeekable(true), mPositionChangeQueued(false), mAudioCompleted(false), mGotDurationFromMetaData(false), mStopDecodeThread(true), mDecodeThreadIdle(false), mStopAudioThread(true), mQuickBuffering(false), mIsRunning(false), @@ -1203,18 +1177,20 @@ uint32_t MediaDecoderStateMachine::PlayF NS_WARN_IF_FALSE(IsPlaying(), "Should be playing"); NS_ASSERTION(!mAudioCaptured, "Audio cannot be captured here!"); // Awaken the decode loop if it's waiting for space to free up in the // audio queue. mDecoder->GetReentrantMonitor().NotifyAll(); } int64_t offset = -1; uint32_t frames = 0; - LOG(PR_LOG_DEBUG, ("%p Decoder playing %d frames of data to stream for AudioData at %lld", - mDecoder.get(), audio->mFrames, audio->mTime)); + if (!PR_GetEnv("MOZ_QUIET")) { + LOG(PR_LOG_DEBUG, ("%p Decoder playing %d frames of data to stream for AudioData at %lld", + mDecoder.get(), audio->mFrames, audio->mTime)); + } mAudioStream->Write(audio->mAudioData, audio->mFrames); offset = audio->mOffset; frames = audio->mFrames; // Dispatch events to the DOM for the audio just written. mEventManager.QueueWrittenAudioData(audio->mAudioData.get(), @@ -1301,16 +1277,18 @@ void MediaDecoderStateMachine::UpdatePla nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(mDecoder, &MediaDecoder::PlaybackPositionChanged); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); } // Notify DOM of any queued up audioavailable events mEventManager.DispatchPendingEvents(GetMediaTime()); + mMetadataManager.DispatchMetadataIfNeeded(mDecoder, aTime); + if (fragmentEnded) { StopPlayback(); } } void MediaDecoderStateMachine::ClearPositionChangeFlag() { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); @@ -1394,22 +1372,31 @@ void MediaDecoderStateMachine::SetMediaE void MediaDecoderStateMachine::SetFragmentEndTime(int64_t aEndTime) { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); mFragmentEndTime = aEndTime < 0 ? aEndTime : aEndTime + mStartTime; } -void MediaDecoderStateMachine::SetSeekable(bool aSeekable) +void MediaDecoderStateMachine::SetTransportSeekable(bool aTransportSeekable) { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); + NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(), + "Should be on main thread or the decoder thread."); mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); - mSeekable = aSeekable; + mTransportSeekable = aTransportSeekable; +} + +void MediaDecoderStateMachine::SetMediaSeekable(bool aMediaSeekable) +{ + NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(), + "Should be on main thread or the decoder thread."); + + mMediaSeekable = aMediaSeekable; } void MediaDecoderStateMachine::Shutdown() { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); // Once we've entered the shutdown state here there's no going back. ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); @@ -1484,16 +1471,22 @@ void MediaDecoderStateMachine::NotifyDat } } } void MediaDecoderStateMachine::Seek(double aTime) { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + + // We need to be able to seek both at a transport level and at a media level + // to seek. + if (!mMediaSeekable) { + return; + } // MediaDecoder::mPlayState should be SEEKING while we seek, and // in that case MediaDecoder shouldn't be calling us. NS_ASSERTION(mState != DECODER_STATE_SEEKING, "We shouldn't already be seeking"); NS_ASSERTION(mState >= DECODER_STATE_DECODING, "We should have loaded metadata"); double t = aTime * static_cast<double>(USECS_PER_S); if (t > INT64_MAX) { @@ -1770,41 +1763,45 @@ nsresult MediaDecoderStateMachine::Decod RenderVideoFrame(videoData, TimeStamp::Now()); } if (mState == DECODER_STATE_SHUTDOWN) { return NS_ERROR_FAILURE; } NS_ASSERTION(mStartTime != -1, "Must have start time"); - NS_ASSERTION((!HasVideo() && !HasAudio()) || - !mSeekable || mEndTime != -1, - "Active seekable media should have end time"); - NS_ASSERTION(!mSeekable || GetDuration() != -1, "Seekable media should have duration"); - LOG(PR_LOG_DEBUG, ("%p Media goes from %lld to %lld (duration %lld) seekable=%d", - mDecoder.get(), mStartTime, mEndTime, GetDuration(), mSeekable)); + MOZ_ASSERT((!HasVideo() && !HasAudio()) || + !(mMediaSeekable && mTransportSeekable) || mEndTime != -1, + "Active seekable media should have end time"); + MOZ_ASSERT(!(mMediaSeekable && mTransportSeekable) || + GetDuration() != -1, "Seekable media should have duration"); + LOG(PR_LOG_DEBUG, ("%p Media goes from %lld to %lld (duration %lld)" + " transportSeekable=%d, mediaSeekable=%d", + mDecoder.get(), mStartTime, mEndTime, GetDuration(), + mTransportSeekable, mMediaSeekable)); // Inform the element that we've loaded the metadata and the first frame, // setting the default framebuffer size for audioavailable events. Also, // if there is audio, let the MozAudioAvailable event manager know about // the metadata. if (HasAudio()) { mEventManager.Init(mInfo.mAudioChannels, mInfo.mAudioRate); // Set the buffer length at the decoder level to be able, to be able // to retrive the value via media element method. The RequestFrameBufferLength // will call the MediaDecoderStateMachine::SetFrameBufferLength(). uint32_t frameBufferLength = mInfo.mAudioChannels * FRAMEBUFFER_LENGTH_PER_CHANNEL; mDecoder->RequestFrameBufferLength(frameBufferLength); } + nsCOMPtr<nsIRunnable> metadataLoadedEvent = - new nsAudioMetadataEventRunner(mDecoder, - mInfo.mAudioChannels, - mInfo.mAudioRate, - HasAudio(), - tags); + new AudioMetadataEventRunner(mDecoder, + mInfo.mAudioChannels, + mInfo.mAudioRate, + HasAudio(), + tags); NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL); if (mState == DECODER_STATE_DECODING_METADATA) { LOG(PR_LOG_DEBUG, ("%p Changed state from DECODING_METADATA to DECODING", mDecoder.get())); StartDecoding(); } if ((mState == DECODER_STATE_DECODING || mState == DECODER_STATE_COMPLETED) && @@ -2169,18 +2166,20 @@ void MediaDecoderStateMachine::RenderVid NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(), "Should be on state machine or decode thread."); mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn(); if (aData->mDuplicate) { return; } - LOG(PR_LOG_DEBUG, ("%p Decoder playing video frame %lld", - mDecoder.get(), aData->mTime)); + if (!PR_GetEnv("MOZ_QUIET")) { + LOG(PR_LOG_DEBUG, ("%p Decoder playing video frame %lld", + mDecoder.get(), aData->mTime)); + } VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { container->SetCurrentFrame(aData->mDisplay, aData->mImage, aTarget); } } int64_t @@ -2695,10 +2694,23 @@ void MediaDecoderStateMachine::SetPreser } bool MediaDecoderStateMachine::IsShutdown() { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); return GetState() == DECODER_STATE_SHUTDOWN; } +void MediaDecoderStateMachine::QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags) +{ + NS_ASSERTION(OnDecodeThread(), "Should be on decode thread."); + mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); + TimedMetadata* metadata = new TimedMetadata; + metadata->mPublishTime = aPublishTime; + metadata->mChannels = aChannels; + metadata->mRate = aRate; + metadata->mHasAudio = aHasAudio; + metadata->mTags = aTags; + mMetadataManager.QueueMetadata(metadata); +} + } // namespace mozilla
--- a/content/media/MediaDecoderStateMachine.h +++ b/content/media/MediaDecoderStateMachine.h @@ -174,20 +174,26 @@ public: // monitor must be obtained before calling this. double GetCurrentTime() const; // Clear the flag indicating that a playback position change event // is currently queued. This is called from the main thread and must // be called with the decode monitor held. void ClearPositionChangeFlag(); - // Called from the main thread to set whether the media resource can - // seek into unbuffered ranges. The decoder monitor must be obtained - // before calling this. - void SetSeekable(bool aSeekable); + // Called from the main thread or the decoder thread to set whether the media + // resource can seek into unbuffered ranges. The decoder monitor must be + // obtained before calling this. + void SetTransportSeekable(bool aSeekable); + + // Called from the main thread or the decoder thread to set whether the media + // can seek to random location. This is not true for chained ogg and WebM + // media without index. The decoder monitor must be obtained before calling + // this. + void SetMediaSeekable(bool aSeekable); // Update the playback position. This can result in a timeupdate event // and an invalidate of the frame being dispatched asynchronously if // there is no such event currently queued. // Only called on the decoder thread. Must be called with // the decode monitor held. void UpdatePlaybackPosition(int64_t aTime); @@ -252,19 +258,24 @@ public: void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset); int64_t GetEndMediaTime() const { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); return mEndTime; } - bool IsSeekable() { + bool IsTransportSeekable() { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); - return mSeekable; + return mTransportSeekable; + } + + bool IsMediaSeekable() { + mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); + return mMediaSeekable; } // Return true if the media is seekable using only buffered ranges. bool IsSeekableInBufferedRanges() { if (mReader) { return mReader->IsSeekableInBufferedRanges(); } return false; @@ -317,16 +328,18 @@ public: void FinishStreamData(); bool HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs); bool HaveEnoughDecodedVideo(); // Returns true if the state machine has shutdown or is in the process of // shutting down. The decoder monitor must be held while calling this. bool IsShutdown(); + void QueueMetadata(int64_t aPublishTime, int aChannels, int aRate, bool aHasAudio, MetadataTags* aTags); + protected: virtual uint32_t GetAmpleVideoFrames() { return mAmpleVideoFrames; } private: class WakeDecoderRunnable : public nsRunnable { public: WakeDecoderRunnable(MediaDecoderStateMachine* aSM) : mMutex("WakeDecoderRunnable"), mStateMachine(aSM) {} @@ -695,19 +708,23 @@ private: // If we've got more than mAmpleVideoFrames decoded video frames waiting in // the video queue, we will not decode any more video frames until some have // been consumed by the play state machine thread. uint32_t mAmpleVideoFrames; // True if we shouldn't play our audio (but still write it to any capturing // streams). bool mAudioCaptured; - // True if the media resource can be seeked. Accessed from the state - // machine and main threads. Synchronised via decoder monitor. - bool mSeekable; + // True if the media resource can be seeked on a transport level. Accessed + // from the state machine and main threads. Synchronised via decoder monitor. + bool mTransportSeekable; + + // True if the media can be seeked. Accessed from the state machine and main + // threads. Synchronised via decoder monitor. + bool mMediaSeekable; // True if an event to notify about a change in the playback // position has been queued, but not yet run. It is set to false when // the event is run. This allows coalescing of these events as they can be // produced many times per second. Synchronised via decoder monitor. // Accessed on main and state machine threads. bool mPositionChangeQueued; @@ -780,12 +797,14 @@ private: // Manager for queuing and dispatching MozAudioAvailable events. The // event manager is accessed from the state machine and audio threads, // and takes care of synchronizing access to its internal queue. AudioAvailableEventManager mEventManager; // Stores presentation info required for playback. The decoder monitor // must be held when accessing this. VideoInfo mInfo; + + mozilla::MediaMetadataManager mMetadataManager; }; } // namespace mozilla; #endif
new file mode 100644 --- /dev/null +++ b/content/media/MediaMetadataManager.h @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#if !defined(MediaMetadataManager_h__) +#define MediaMetadataManager_h__ +#include "VideoUtils.h" +#include "mozilla/LinkedList.h" +#include "AbstractMediaDecoder.h" +#include "nsAutoPtr.h" + +namespace mozilla { + + // A struct that contains the metadata of a media, and the time at which those + // metadata should start to be reported. + class TimedMetadata : public LinkedListElement<TimedMetadata> { + public: + // The time, in microseconds, at which those metadata should be available. + int64_t mPublishTime; + // The metadata. The ownership is transfered to the element when dispatching to + // the main threads. + nsAutoPtr<MetadataTags> mTags; + // The sample rate of this media. + int mRate; + // The number of channel of this media. + int mChannels; + // True if this media has an audio track. + bool mHasAudio; + }; + + // This class encapsulate the logic to give the metadata from the reader to + // the content, at the right time. + class MediaMetadataManager + { + public: + ~MediaMetadataManager() { + TimedMetadata* element; + while((element = mMetadataQueue.popFirst()) != nullptr) { + delete element; + } + } + void QueueMetadata(TimedMetadata* aMetadata) { + mMetadataQueue.insertBack(aMetadata); + } + + void DispatchMetadataIfNeeded(AbstractMediaDecoder* aDecoder, double aCurrentTime) { + TimedMetadata* metadata = mMetadataQueue.getFirst(); + while (metadata && aCurrentTime >= static_cast<double>(metadata->mPublishTime) / USECS_PER_S) { + nsCOMPtr<nsIRunnable> metadataUpdatedEvent = + new mozilla::AudioMetadataEventRunner(aDecoder, + metadata->mChannels, + metadata->mRate, + metadata->mHasAudio, + metadata->mTags.forget()); + NS_DispatchToMainThread(metadataUpdatedEvent, NS_DISPATCH_NORMAL); + mMetadataQueue.popFirst(); + metadata = mMetadataQueue.getFirst(); + } + } + protected: + LinkedList<TimedMetadata> mMetadataQueue; + }; +} + +#endif
--- a/content/media/MediaResource.cpp +++ b/content/media/MediaResource.cpp @@ -209,20 +209,24 @@ ChannelMediaResource::OnStartRequest(nsI rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("Content-Duration"), durationText); if (NS_FAILED(rv)) { rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-AMZ-Meta-Content-Duration"), durationText); } if (NS_FAILED(rv)) { rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-Content-Duration"), durationText); } + // If there is no Content-Duration header, or if the value for this header + // is not valid, set the media as being infinite. if (NS_SUCCEEDED(rv)) { double duration = durationText.ToDouble(&ec); if (ec == NS_OK && duration >= 0) { mDecoder->SetDuration(duration); + } else { + mDecoder->SetInfinite(true); } } else { mDecoder->SetInfinite(true); } } // Check response code for byte-range requests (seeking, chunk requests). if (!mByteRange.IsNull() && (responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) { @@ -300,18 +304,18 @@ ChannelMediaResource::OnStartRequest(nsI // support seeking. seekable = responseStatus == HTTP_PARTIAL_RESPONSE_CODE || acceptsRanges; if (seekable) { mDecoder->SetInfinite(false); } } - mDecoder->SetSeekable(seekable); - mCacheStream.SetSeekable(seekable); + mDecoder->SetTransportSeekable(seekable); + mCacheStream.SetTransportSeekable(seekable); nsCOMPtr<nsICachingChannel> cc = do_QueryInterface(aRequest); if (cc) { bool fromCache = false; rv = cc->IsFromCache(&fromCache); if (NS_SUCCEEDED(rv) && !fromCache) { cc->SetCacheAsFile(true); } @@ -414,17 +418,17 @@ ChannelMediaResource::OnStopRequest(nsIR // Note that aStatus might have succeeded --- this might be a normal close // --- even in situations where the server cut us off because we were // suspended. So we need to "reopen on error" in that case too. The only // cases where we don't need to reopen are when *we* closed the stream. // But don't reopen if we need to seek and we don't think we can... that would // cause us to just re-read the stream, which would be really bad. if (mReopenOnError && aStatus != NS_ERROR_PARSED_DATA_CACHED && aStatus != NS_BINDING_ABORTED && - (mOffset == 0 || mCacheStream.IsSeekable())) { + (mOffset == 0 || mCacheStream.IsTransportSeekable())) { // If the stream did close normally, then if the server is seekable we'll // just seek to the end of the resource and get an HTTP 416 error because // there's nothing there, so this isn't bad. nsresult rv = CacheClientSeek(mOffset, false); if (NS_SUCCEEDED(rv)) return rv; // If the reopen/reseek fails, just fall through and treat this // error as fatal. @@ -798,17 +802,17 @@ void ChannelMediaResource::Suspend(bool } nsHTMLMediaElement* element = owner->GetMediaElement(); if (!element) { // Shutting down; do nothing. return; } if (mChannel) { - if (aCloseImmediately && mCacheStream.IsSeekable()) { + if (aCloseImmediately && mCacheStream.IsTransportSeekable()) { // Kill off our channel right now, but don't tell anyone about it. mIgnoreClose = true; CloseChannel(); element->DownloadSuspended(); } else if (mSuspendCount == 0) { { MutexAutoLock lock(mLock); mChannelStatistics.Stop(TimeStamp::Now());
--- a/content/media/dash/DASHRepDecoder.cpp +++ b/content/media/dash/DASHRepDecoder.cpp @@ -278,20 +278,20 @@ DASHRepDecoder::SetDuration(double aDura void DASHRepDecoder::SetInfinite(bool aInfinite) { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); if (mMainDecoder) { mMainDecoder->SetInfinite(aInfinite); } } void -DASHRepDecoder::SetSeekable(bool aSeekable) +DASHRepDecoder::SetMediaSeekable(bool aMediaSeekable) { NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); - if (mMainDecoder) { mMainDecoder->SetSeekable(aSeekable); } + if (mMainDecoder) { mMainDecoder->SetMediaSeekable(aMediaSeekable); } } void DASHRepDecoder::Progress(bool aTimer) { if (mMainDecoder) { mMainDecoder->Progress(aTimer); } }
--- a/content/media/dash/DASHRepDecoder.h +++ b/content/media/dash/DASHRepDecoder.h @@ -91,17 +91,17 @@ public: // This is called via a channel listener if it can pick up the duration // from a content header. Must be called from the main thread only. virtual void SetDuration(double aDuration); // Set media stream as infinite. Called on the main thread only. void SetInfinite(bool aInfinite); // Sets media stream as seekable. Called on main thread only. - void SetSeekable(bool aSeekable); + void SetMediaSeekable(bool aSeekable); // Fire progress events if needed according to the time and byte // constraints outlined in the specification. aTimer is true // if the method is called as a result of the progress timer rather // than the result of downloaded data. void Progress(bool aTimer); // Called as data arrives on the stream and is read into the cache. Called
--- a/content/media/ogg/OggReader.cpp +++ b/content/media/ogg/OggReader.cpp @@ -13,16 +13,17 @@ #include "opus/opus.h" extern "C" { #include "opus/opus_multistream.h" } #endif #include "nsTimeRanges.h" #include "mozilla/TimeStamp.h" #include "VorbisUtils.h" +#include "MediaMetadataManager.h" namespace mozilla { // On B2G estimate the buffered ranges rather than calculating them explicitly. // This prevents us doing I/O on the main thread, which is prohibited in B2G. #ifdef MOZ_WIDGET_GONK #define OGG_ESTIMATE_BUFFERED 1 #endif @@ -72,26 +73,29 @@ PageSync(MediaResource* aResource, int& aSkippedBytes); // Chunk size to read when reading Ogg files. Average Ogg page length // 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), mOpusState(nullptr), mOpusEnabled(MediaDecoder::IsOpusEnabled()), mSkeletonState(nullptr), mVorbisSerial(0), mOpusSerial(0), mTheoraSerial(0), mOpusPreSkip(0), - mPageOffset(0) + mPageOffset(0), + mIsChained(false), + mDecodedAudioFrames(0) { MOZ_COUNT_CTOR(OggReader); memset(&mTheoraInfo, 0, sizeof(mTheoraInfo)); } OggReader::~OggReader() { ogg_sync_clear(&mOggState); @@ -395,16 +399,19 @@ nsresult OggReader::DecodeVorbis(ogg_pac int64_t duration = mVorbisState->Time((int64_t)frames); int64_t startTime = mVorbisState->Time(endFrame - frames); mAudioQueue.Push(new AudioData(mPageOffset, startTime, duration, frames, buffer.forget(), channels)); + + mDecodedAudioFrames += frames; + endFrame -= frames; if (vorbis_synthesis_read(&mVorbisState->mDsp, frames) != 0) { return NS_ERROR_FAILURE; } } return NS_OK; } #ifdef MOZ_OPUS @@ -539,16 +546,19 @@ nsresult OggReader::DecodeOpus(ogg_packe int64_t startTime = mOpusState->Time(startFrame); int64_t endTime = mOpusState->Time(endFrame); mAudioQueue.Push(new AudioData(mPageOffset, startTime, endTime - startTime, frames, buffer.forget(), channels)); + + mDecodedAudioFrames += frames; + return NS_OK; } #endif /* MOZ_OPUS */ bool OggReader::DecodeAudioData() { NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); NS_ASSERTION(mVorbisState != nullptr || mOpusState != nullptr, @@ -579,27 +589,136 @@ bool OggReader::DecodeAudioData() if (mVorbisState) { DecodeVorbis(packet); #ifdef MOZ_OPUS } else if (mOpusState) { DecodeOpus(packet); #endif } - if (packet->e_o_s) { + if ((packet->e_o_s) && (!ReadOggChain())) { // We've encountered an end of bitstream packet, or we've hit the end of // file while trying to decode, so inform the audio queue that there'll // be no more samples. mAudioQueue.Finish(); return false; } return true; } +void OggReader::SetChained(bool aIsChained) { + { + ReentrantMonitorAutoEnter mon(mMonitor); + mIsChained = aIsChained; + } + { + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + mDecoder->SetMediaSeekable(false); + } +} + +bool OggReader::ReadOggChain() +{ + + bool chained = false; + OpusState* newOpusState = nullptr; + VorbisState* newVorbisState = nullptr; + int channels = 0; + long rate = 0; + MetadataTags* tags = nullptr; + + if (HasVideo() || HasSkeleton() || !HasAudio()) { + return false; + } + + ogg_page page; + int64_t pageOffset = ReadOggPage(&page); + if ((pageOffset == -1) || (!ogg_page_bos(&page))) { + return false; + } + + int serial = ogg_page_serialno(&page); + if (mCodecStates.Get(serial, nullptr)) { + return false; + } + + nsAutoPtr<OggCodecState> codecState; + codecState = OggCodecState::Create(&page); + if (!codecState) { + return false; + } + + if (mVorbisState && (codecState->GetType() == OggCodecState::TYPE_VORBIS)) { + newVorbisState = static_cast<VorbisState*>(codecState.get()); + } +#ifdef MOZ_OPUS + else if (mOpusState && (codecState->GetType() == OggCodecState::TYPE_OPUS)) { + newOpusState = static_cast<OpusState*>(codecState.get()); + } +#endif + else { + return false; + } + + mCodecStates.Put(serial, codecState.forget()); + mKnownStreams.AppendElement(serial); + OggCodecState* state = nullptr; + mCodecStates.Get(serial, &state); + + NS_ENSURE_TRUE(state, false); + + if (NS_FAILED(state->PageIn(&page))) { + return false; + } + + if ((newVorbisState && ReadHeaders(newVorbisState)) && + (mVorbisState->mInfo.rate == newVorbisState->mInfo.rate) && + (mVorbisState->mInfo.channels == newVorbisState->mInfo.channels)) { + mVorbisState->Reset(); + mVorbisState = newVorbisState; + mVorbisSerial = mVorbisState->mSerial; + LOG(PR_LOG_DEBUG, ("New vorbis ogg link, serial=%d\n", mVorbisSerial)); + chained = true; + rate = mVorbisState->mInfo.rate; + channels = mVorbisState->mInfo.channels; + tags = mVorbisState->GetTags(); + } + +#ifdef MOZ_OPUS + if ((newOpusState && ReadHeaders(newOpusState)) && + (mOpusState->mRate == newOpusState->mRate) && + (mOpusState->mChannels == newOpusState->mChannels) && + (mOpusState->mPreSkip == newOpusState->mPreSkip)) { + mOpusState->Reset(); + mOpusState = newOpusState; + mOpusSerial = mOpusState->mSerial; + chained = true; + rate = mOpusState->mRate; + channels = mOpusState->mChannels; + tags = mOpusState->GetTags(); + } +#endif + + if (chained) { + SetChained(true); + { + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + mDecoder->QueueMetadata((mDecodedAudioFrames * USECS_PER_S) / rate, + channels, + rate, + HasAudio(), + tags); + } + return true; + } + + return false; +} + nsresult OggReader::DecodeTheora(ogg_packet* aPacket, int64_t aTimeThreshold) { NS_ASSERTION(aPacket->granulepos >= TheoraVersion(&mTheoraState->mInfo,3,2,1), "Packets must have valid granulepos and packetno"); int ret = th_decode_packetin(mTheoraState->mCtx, aPacket, 0); if (ret != 0 && ret != TH_DUPFRAME) { return NS_ERROR_FAILURE; @@ -938,16 +1057,17 @@ int64_t OggReader::RangeEndTime(int64_t OggCodecState* codecState = nullptr; mCodecStates.Get(serial, &codecState); if (!codecState) { // This page is from a bitstream which we haven't encountered yet. // It's probably from a new "link" in a "chained" ogg. Don't // bother even trying to find a duration... + SetChained(true); endTime = -1; break; } int64_t t = codecState->Time(granulepos); if (t != -1) { endTime = t; } @@ -1202,16 +1322,18 @@ nsresult OggReader::SeekInUnbuffered(int } nsresult OggReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) { 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; if (HasAudio() && mOpusState){ adjustedTarget = NS_MAX(aStartTime, aTarget - SEEK_OPUS_PREROLL); } @@ -1598,16 +1720,21 @@ nsresult OggReader::SeekBisection(int64_ SEEK_LOG(PR_LOG_DEBUG, ("Seek complete in %d bisections.", hops)); return NS_OK; } nsresult OggReader::GetBuffered(nsTimeRanges* aBuffered, int64_t aStartTime) { + { + mozilla::ReentrantMonitorAutoEnter mon(mMonitor); + if (mIsChained) + return NS_ERROR_FAILURE; + } #ifdef OGG_ESTIMATE_BUFFERED MediaResource* stream = mDecoder->GetResource(); int64_t durationUs = 0; { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); durationUs = mDecoder->GetMediaDuration(); } GetEstimatedBufferedTimeRanges(stream, durationUs, aBuffered); @@ -1693,16 +1820,17 @@ nsresult OggReader::GetBuffered(nsTimeRa startOffset += page.header_len + page.body_len; continue; } else { // Page is for a stream we don't know about (possibly a chained // ogg), return OK to abort the finding any further ranges. This // prevents us searching through the rest of the media when we // may not be able to extract timestamps from it. + SetChained(true); return NS_OK; } } if (startTime != -1) { // We were able to find a start time for that range, see if we can // find an end time. int64_t endTime = RangeEndTime(startOffset, endOffset, true);
--- a/content/media/ogg/OggReader.h +++ b/content/media/ogg/OggReader.h @@ -46,22 +46,25 @@ public: return mTheoraState != 0 && mTheoraState->mActive; } virtual nsresult ReadMetadata(VideoInfo* aInfo, MetadataTags** aTags); virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime); virtual nsresult GetBuffered(nsTimeRanges* aBuffered, int64_t aStartTime); - // We use bisection to seek in buffered range. + // We use bisection to seek in buffered range, but we don't allow seeking in a + // chained ogg file. virtual bool IsSeekableInBufferedRanges() { return true; } private: + // This monitor should be taken when reading or writing to mIsChained. + ReentrantMonitor mMonitor; // Specialized Reset() method to signal if the seek is // to the start of the stream. nsresult ResetDecode(bool start); bool HasSkeleton() { return mSkeletonState != 0 && mSkeletonState->mActive; } @@ -211,16 +214,23 @@ private: int64_t ReadOggPage(ogg_page* aPage); // Reads and decodes header packets for aState, until either header decode // fails, or is complete. Initializes the codec state before returning. // Returns true if reading headers and initializtion of the stream // succeeds. bool ReadHeaders(OggCodecState* aState); + // Reads the next link in the chain. + bool ReadOggChain(); + + // Set this media as being a chain and notifies the state machine that the + // media is no longer seekable. + void SetChained(bool aIsChained); + // Returns the next Ogg packet for an bitstream/codec state. Returns a // pointer to an ogg_packet on success, or nullptr if the read failed. // The caller is responsible for deleting the packet and its |packet| field. ogg_packet* NextOggPacket(OggCodecState* aCodecState); // Fills aTracks with the serial numbers of each active stream, for use by // various SkeletonState functions. void BuildSerialList(nsTArray<uint32_t>& aTracks); @@ -269,13 +279,20 @@ private: // The offset of the end of the last page we've read, or the start of // the page we're about to read. int64_t mPageOffset; // The picture region inside Theora frame to be displayed, if we have // a Theora video track. nsIntRect mPicture; + + // True if we are decoding a chained ogg. Reading or writing to this member + // should be done with |mMonitor| acquired. + bool mIsChained; + + // Number of audio frames decoded so far. + int64_t mDecodedAudioFrames; }; } // namespace mozilla #endif
--- a/content/media/plugins/MediaPluginHost.cpp +++ b/content/media/plugins/MediaPluginHost.cpp @@ -12,16 +12,23 @@ #include "nsXPCOMStrings.h" #include "nsISeekableStream.h" #include "pratom.h" #include "MediaPluginReader.h" #include "nsIGfxInfo.h" #include "MPAPI.h" +#if defined(ANDROID) || defined(MOZ_WIDGET_GONK) +#include "android/log.h" +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaPluginHost" , ## args) +#else +#define ALOG(args...) /* do nothing */ +#endif + using namespace MPAPI; Decoder::Decoder() : mResource(NULL), mPrivate(NULL) { } namespace mozilla { @@ -87,56 +94,110 @@ static bool GetIntPref(const char* aPref static PluginHost sPluginHost = { Read, GetLength, SetMetaDataReadMode, SetPlaybackReadMode, GetIntPref }; -void MediaPluginHost::TryLoad(const char *name) +// Return true if Omx decoding is supported on the device. This checks the +// built in whitelist/blacklist and preferences to see if that is overridden. +static bool IsOmxSupported() { bool forceEnabled = Preferences::GetBool("stagefright.force-enabled", false); bool disabled = Preferences::GetBool("stagefright.disabled", false); if (disabled) { NS_WARNING("XXX stagefright disabled\n"); - return; + return false; } if (!forceEnabled) { nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1"); if (gfxInfo) { int32_t status; if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, &status))) { if (status != nsIGfxInfo::FEATURE_NO_INFO) { NS_WARNING("XXX stagefright blacklisted\n"); - return; + return false; } } } } + return true; +} - PRLibrary *lib = PR_LoadLibrary(name); - if (lib) { - Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST")); - if (manifest) - mPlugins.AppendElement(manifest); +// Return the name of the shared library that implements Omx based decoding. This varies +// depending on libstagefright version installed on the device and whether it is B2G vs Android. +// nullptr is returned if Omx decoding is not supported on the device, +static const char* GetOmxLibraryName() +{ + if (!IsOmxSupported()) + return nullptr; + +#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK) + nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1"); + NS_ASSERTION(infoService, "Could not find a system info service"); + + int32_t version; + nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("version"), &version); + if (NS_SUCCEEDED(rv)) { + ALOG("Android Version is: %d", version); + } + + nsAutoString release_version; + rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("release_version"), release_version); + if (NS_SUCCEEDED(rv)) { + ALOG("Android Release Version is: %s", NS_LossyConvertUTF16toASCII(release_version).get()); } + + if (version == 13 || version == 12 || version == 11) { + return "lib/libomxpluginhc.so"; + } + else if (version == 10 && release_version >= NS_LITERAL_STRING("2.3.6")) { + // Gingerbread versions from 2.3.6 and above have a different DataSource + // layout to those on 2.3.5 and below. + return "lib/libomxplugingb.so"; + } + else if (version == 9 || (version == 10 && release_version <= NS_LITERAL_STRING("2.3.5"))) { + // Gingerbread versions from 2.3.5 and below have a different DataSource + // than 2.3.6 and above. + return "lib/libomxplugingb235.so"; + } + else if (version < 9) { + // Froyo and below are not supported + return nullptr; + } + + // Default libomxplugin for non-gingerbread devices + return "lib/libomxplugin.so"; + +#elif defined(ANDROID) && defined(MOZ_WIDGET_GONK) + return "libomxplugin.so"; +#endif } MediaPluginHost::MediaPluginHost() { MOZ_COUNT_CTOR(MediaPluginHost); -#if defined(ANDROID) && !defined(MOZ_WIDGET_GONK) - TryLoad("lib/libomxplugin.so"); -#elif defined(ANDROID) && defined(MOZ_WIDGET_GONK) - TryLoad("libomxplugin.so"); -#endif + + const char* name = GetOmxLibraryName(); + ALOG("Loading OMX Plugin: %s", name ? name : "nullptr"); + if (name) { + PRLibrary *lib = PR_LoadLibrary(name); + if (lib) { + Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST")); + if (manifest) { + mPlugins.AppendElement(manifest); + ALOG("OMX plugin successfully loaded"); + } + } + } } MediaPluginHost::~MediaPluginHost() { MOZ_COUNT_DTOR(MediaPluginHost); } bool MediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const** aCodecs) {
--- a/content/media/plugins/MediaPluginHost.h +++ b/content/media/plugins/MediaPluginHost.h @@ -12,17 +12,16 @@ namespace mozilla { class MediaPluginReader; class MediaPluginHost { nsTArray<MPAPI::Manifest *> mPlugins; MPAPI::Manifest *FindPlugin(const nsACString& aMimeType); - void TryLoad(const char *name); public: MediaPluginHost(); ~MediaPluginHost(); static void Shutdown(); bool FindDecoder(const nsACString& aMimeType, const char* const** aCodecs); MPAPI::Decoder *CreateDecoder(mozilla::MediaResource *aResource, const nsACString& aMimeType);
--- a/content/media/plugins/MediaPluginReader.cpp +++ b/content/media/plugins/MediaPluginReader.cpp @@ -155,16 +155,19 @@ bool MediaPluginReader::DecodeVideoFrame if (!frame.mKeyFrame) { ++parsed; continue; } #endif aKeyframeSkip = false; } + if (frame.mSize == 0) + return true; + VideoData::YCbCrBuffer b; b.mPlanes[0].mData = static_cast<uint8_t *>(frame.Y.mData); b.mPlanes[0].mStride = frame.Y.mStride; b.mPlanes[0].mHeight = frame.Y.mHeight; b.mPlanes[0].mWidth = frame.Y.mWidth; b.mPlanes[0].mOffset = frame.Y.mOffset; b.mPlanes[0].mSkip = frame.Y.mSkip;
--- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -202,16 +202,24 @@ MOCHITEST_FILES += \ bug523816.ogv \ bug533822.ogg \ bug557094.ogv \ bug556821.ogv \ bug580982.webm \ bug603918.webm \ bug604067.webm \ chain.ogv \ + chain.ogg \ + chain.opus \ + variable-samplerate.ogg \ + variable-samplerate.opus \ + variable-channel.ogg \ + variable-channel.opus \ + chained-video.ogv \ + chained-audio-video.ogg \ dirac.ogg \ multiple-bos.ogg \ split.webm \ seek.ogv \ seek.webm \ seek.yuv \ short-video.ogv \ small-shot.ogg \ @@ -294,16 +302,17 @@ MOCHITEST_FILES += \ contentDuration2.sjs \ contentDuration3.sjs \ contentDuration4.sjs \ contentDuration5.sjs \ contentDuration6.sjs \ contentDuration7.sjs \ test_framebuffer.html \ test_seekable2.html \ + test_chaining.html \ $(NULL) else MOCHITEST_FILES += \ test_can_play_type_no_ogg.html \ $(NULL) endif ifdef MOZ_WEBM
new file mode 100644 index 0000000000000000000000000000000000000000..3535b280f41ea7b402b95af2e6dfb5e60869d1aa GIT binary patch literal 63610 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 KfoN(0_&)$tn|#0k
new file mode 100644 index 0000000000000000000000000000000000000000..9fa67f94c3cbcca47956507d076bda72fd7496b5 GIT binary patch literal 50101 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­8EK)l73S*$NrMe7c!b<!jI{EF+#CqBzTh-%^ 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%0Dk>Cc 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
new file mode 100644 index 0000000000000000000000000000000000000000..adda68bb47edf95228f8ce364f585e4abb977027 GIT binary patch literal 92552 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 Y;qC=HKQ}-aSe7tV$?W9L(?q5J1FLxkr2qf`
new file mode 100644 index 0000000000000000000000000000000000000000..a6288ef6c9e4b0df3bdb736c015b03b485d99d6f GIT binary patch literal 57906 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 J|0@{re*l(i7!v>h
--- a/content/media/test/manifest.js +++ b/content/media/test/manifest.js @@ -326,16 +326,42 @@ var gDecodeErrorTests = [ { name:"bogus.duh", type:"bogus/duh" } ]; // These are files that are used for media fragments tests var gFragmentTests = [ { name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444 } ]; +// Used by test_chaining.html. The |links| attributes is the number of links in +// this file that we should be able to play. +var gChainingTests = [ + // Vorbis and Opus chained file. They have user comments |index=n| where `n` + // is the index of this segment in the file, 0 indexed. + { name:"chain.ogg", type:"audio/ogg", links: 4}, + { name:"chain.opus", type:"audio/ogg; codec=opus", links: 4}, + // Those files are chained files with a different number of channels in each + // part. This is not supported and should stop playing after the first part. + { name:"variable-channel.ogg", type:"audio/ogg", links: 1 }, + { name:"variable-channel.opus", type:"audio/ogg; codec=opus", links: 1 }, + // Those files are chained files with a different sample rate in each + // part. This is not supported and should stop playing after the first part. + { name:"variable-samplerate.ogg", type:"audio/ogg", links: 1 }, + // Opus decoding in Firefox outputs 48 kHz PCM despite having a different + // original sample rate, so we can safely play Opus chained media that have + // different samplerate accross links. + { name:"variable-samplerate.opus", type:"audio/ogg; codec=opus", links: 2 }, + // A chained video file. We don't support those, so only one link should be + // reported. + { name:"chained-video.ogv", type:"video/ogg", links: 1 }, + // A file that consist in 4 links of audio, then another link that has video. + // We should stop right after the 4 audio links. + { name:"chained-audio-video.ogg", type:"video/ogg", links: 4 }, + { name:"bogus.duh", type:"bogus/duh" } +]; // These are files with non-trivial tag sets. // Used by test_metadata.html. var gMetadataTests = [ // Ogg Vorbis files { name:"short-video.ogv", tags: { TITLE:"Lepidoptera", ARTIST:"Epoq",
new file mode 100644 --- /dev/null +++ b/content/media/test/test_chaining.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Media test: chained ogg files.</title> + <meta charset='utf-8'> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="manifest.js"></script> +</head> +<body> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var manager = new MediaTestManager; + +function finish_test(element) { + if (element.parentNode) + element.parentNode.removeChild(element); + manager.finished(element.token); +} + +function onended(e) { + var t = e.target; + is(t._metadataCount, t._links, "We should have received "+ t._links + + " metadataloaded event. " + t.src); + + // If we encounter a file that has links with a different numbers of channel, + // we stop the decoding at the end of the first link. Hence, we report normal + // |seekable| and |buffered| values. + if (t._links != 1) { + is(t.seekable.length, 0, "No seekable ranges should be reported." + t.src); + is(t.buffered.length, 0, "No buffered region should be reported." + t.src); + } + + is(t.played.length, 1, "The played region should be continuous." + t.src); + + if (t._links != 1) { + var oldCurrentTime = t.currentTime; + t.currentTime = 0.0; + is(t.currentTime, oldCurrentTime, + "Seeking should be disabled when playing chained media." + t.src); + } + + finish_test(t); +} + +function onmetadataloaded(e) { + var t = e.target; + if (! t._metadataCount) { + t._metadataCount = 0; + } + + if (t._metadataCount > 1 && t._links === 1) { + ok(false, "We should receive only one \"loadedmetadata\" event for a chained file we don't support.") + } + + // We should be able to assert equality here, but somehow it fails (rarely but + // still) on try. Instead, we give it a little slack and assert that the index + // increases monotonically. + ok(t.mozGetMetadata().index >= t._metadataCount || t._links === 1, + "The metadata index value should increase." + t.src); + + // The files have all a user comment name 'index' that increments at each link + // in the chained media. + t._metadataCount++; + if (!t.playing && !t.ended) { + t.play(); + } +} + +function startTest(test, token) { + var elemType = /^audio/.test(test.type) ? "audio" : "video"; + var element = document.createElement(elemType); + document.body.appendChild(element); + manager.started(token); + element._links= test.links; + element.src = test.name; + element.token = token; + element.controls = true; + element.addEventListener("loadedmetadata", onmetadataloaded); + element.addEventListener("ended", onended); +} + +manager.runTests(gChainingTests, startTest); +</script> +</pre> +</body> +</html>
new file mode 100644 index 0000000000000000000000000000000000000000..77e116889cd9973f6033e65ed47bb513849b6639 GIT binary patch literal 27749 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