From d20d0642235ff4bb763476e16a760ae6a7b8c357 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Fri, 21 Mar 2014 11:52:01 -0700 Subject: [PATCH 01/53] bug 985021 - mozilla::pkix: temporarily accept pathLenConstraint in EE basic constraints extensions r=briansmith --- security/pkix/lib/pkixcheck.cpp | 65 +++++++++++++++++++++++++++++++-- security/pkix/lib/pkixder.h | 17 +++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/security/pkix/lib/pkixcheck.cpp b/security/pkix/lib/pkixcheck.cpp index 1728b0b57c07..0ba8eab42bb6 100644 --- a/security/pkix/lib/pkixcheck.cpp +++ b/security/pkix/lib/pkixcheck.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include + #include "pkix/pkix.h" #include "pkixcheck.h" #include "pkixder.h" @@ -147,6 +149,62 @@ CheckCertificatePolicies(BackCert& cert, EndEntityOrCA endEntityOrCA, return RecoverableError; } +// BasicConstraints ::= SEQUENCE { +// cA BOOLEAN DEFAULT FALSE, +// pathLenConstraint INTEGER (0..MAX) OPTIONAL } +der::Result +DecodeBasicConstraints(const SECItem* encodedBasicConstraints, + CERTBasicConstraints& basicConstraints) +{ + PR_ASSERT(encodedBasicConstraints); + if (!encodedBasicConstraints) { + return der::Fail(SEC_ERROR_INVALID_ARGS); + } + + basicConstraints.isCA = false; + basicConstraints.pathLenConstraint = 0; + + der::Input input; + if (input.Init(encodedBasicConstraints->data, encodedBasicConstraints->len) + != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + + if (der::ExpectTagAndIgnoreLength(input, der::SEQUENCE) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + + bool isCA = false; + if (der::OptionalBoolean(input, isCA) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + basicConstraints.isCA = isCA; + + if (input.Peek(der::INTEGER)) { + SECItem pathLenConstraintEncoded; + if (der::Integer(input, pathLenConstraintEncoded) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + long pathLenConstraint = DER_GetInteger(&pathLenConstraintEncoded); + if (pathLenConstraint >= std::numeric_limits::max() || + pathLenConstraint < 0) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + basicConstraints.pathLenConstraint = static_cast(pathLenConstraint); + // TODO(bug 985025): If isCA is false, pathLenConstraint MUST NOT + // be included (as per RFC 5280 section 4.2.1.9), but for compatibility + // reasons, we don't check this for now. + } else if (basicConstraints.isCA) { + // If this is a CA but the path length is omitted, it is unlimited. + basicConstraints.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; + } + + if (der::End(input) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + return der::Success; +} + // RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints) Result CheckBasicConstraints(const BackCert& cert, @@ -156,10 +214,9 @@ CheckBasicConstraints(const BackCert& cert, { CERTBasicConstraints basicConstraints; if (cert.encodedBasicConstraints) { - SECStatus rv = CERT_DecodeBasicConstraintValue(&basicConstraints, - cert.encodedBasicConstraints); - if (rv != SECSuccess) { - return MapSECStatus(rv); + if (DecodeBasicConstraints(cert.encodedBasicConstraints, + basicConstraints) != der::Success) { + return RecoverableError; } } else { // Synthesize a non-CA basic constraints by default diff --git a/security/pkix/lib/pkixder.h b/security/pkix/lib/pkixder.h index b9800c2d5162..608466af2b5b 100644 --- a/security/pkix/lib/pkixder.h +++ b/security/pkix/lib/pkixder.h @@ -380,6 +380,23 @@ Boolean(Input& input, /*out*/ bool& value) } } +// This is for any BOOLEAN DEFAULT FALSE. +// (If it is present and false, this is a bad encoding.) +inline Result +OptionalBoolean(Input& input, /*out*/ bool& value) +{ + value = false; + if (input.Peek(BOOLEAN)) { + if (Boolean(input, value) != Success) { + return Failure; + } + if (!value) { + return Fail(SEC_ERROR_BAD_DER); + } + } + return Success; +} + inline Result Enumerated(Input& input, uint8_t& value) { From 29c628c5ebbfd1ca2315169a3d4d42b0fb370502 Mon Sep 17 00:00:00 2001 From: Chadd Williams Date: Fri, 21 Mar 2014 17:48:08 -0400 Subject: [PATCH 02/53] Bug 980493 - Transition FrameMetrics::mScrollId to use a getter/setter. r=botond --HG-- extra : histedit_source : 1c84496d4b61f019e6e6cc24591ee3a10434e4cc --- dom/ipc/TabChild.cpp | 6 ++--- gfx/layers/FrameMetrics.h | 22 ++++++++++++++----- gfx/layers/LayersLogging.cpp | 2 +- gfx/layers/client/ClientTiledThebesLayer.cpp | 2 +- .../client/SimpleTiledContentClient.cpp | 2 +- gfx/layers/client/TiledContentClient.cpp | 2 +- gfx/layers/composite/APZCTreeManager.cpp | 2 +- .../composite/AsyncCompositionManager.cpp | 4 ++-- gfx/layers/composite/ThebesLayerComposite.cpp | 2 +- gfx/layers/ipc/AsyncPanZoomController.cpp | 12 +++++----- gfx/layers/ipc/CompositorChild.cpp | 2 +- .../gtest/TestAsyncPanZoomController.cpp | 6 ++--- layout/base/nsDisplayList.cpp | 2 +- layout/ipc/RenderFrameParent.cpp | 8 +++---- widget/gonk/ParentProcessController.cpp | 4 ++-- widget/windows/winrt/APZController.cpp | 6 ++--- widget/xpwidgets/APZCCallbackHelper.cpp | 12 +++++----- 17 files changed, 53 insertions(+), 43 deletions(-) diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 9b3ed3b8b0af..8e6720e7f249 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -628,7 +628,7 @@ TabChild::HandlePossibleViewportChange() defaultZoom <= viewportInfo.GetMaxZoom()); metrics.SetZoom(defaultZoom); - metrics.mScrollId = viewId; + metrics.SetScrollId(viewId); } metrics.mCumulativeResolution = metrics.GetZoom() / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1); @@ -1472,7 +1472,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName, bool TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics) { - MOZ_ASSERT(aFrameMetrics.mScrollId != FrameMetrics::NULL_SCROLL_ID); + MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID); if (aFrameMetrics.mIsRoot) { nsCOMPtr utils(GetDOMWindowUtils()); @@ -1485,7 +1485,7 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics) // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe. // This requires special handling. nsCOMPtr content = nsLayoutUtils::FindContentFor( - aFrameMetrics.mScrollId); + aFrameMetrics.GetScrollId()); if (content) { FrameMetrics newSubFrameMetrics(aFrameMetrics); APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics); diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index cf3c5e48711e..77825794a9fb 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -71,7 +71,6 @@ public: , mDisplayPort(0, 0, 0, 0) , mCriticalDisplayPort(0, 0, 0, 0) , mViewport(0, 0, 0, 0) - , mScrollId(NULL_SCROLL_ID) , mScrollableRect(0, 0, 0, 0) , mResolution(1) , mCumulativeResolution(1) @@ -81,6 +80,7 @@ public: , mMayHaveTouchListeners(false) , mIsRoot(false) , mHasScrollgrab(false) + , mScrollId(NULL_SCROLL_ID) , mScrollOffset(0, 0) , mZoom(1) , mUpdateScrollOffset(false) @@ -97,7 +97,6 @@ public: mDisplayPort.IsEqualEdges(aOther.mDisplayPort) && mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) && mViewport.IsEqualEdges(aOther.mViewport) && - mScrollId == aOther.mScrollId && mScrollableRect.IsEqualEdges(aOther.mScrollableRect) && mResolution == aOther.mResolution && mCumulativeResolution == aOther.mCumulativeResolution && @@ -105,6 +104,7 @@ public: mMayHaveTouchListeners == aOther.mMayHaveTouchListeners && mPresShellId == aOther.mPresShellId && mIsRoot == aOther.mIsRoot && + mScrollId == aOther.mScrollId && mScrollOffset == aOther.mScrollOffset && mHasScrollgrab == aOther.mHasScrollgrab && mUpdateScrollOffset == aOther.mUpdateScrollOffset; @@ -265,9 +265,6 @@ public: // meaningless and invalid. CSSRect mViewport; - // A unique ID assigned to each scrollable frame. - ViewID mScrollId; - // The scrollable bounds of a frame. This is determined by reflow. // Ordinarily the x and y will be 0 and the width and height will be the // size of the element being scrolled. However for RTL pages or elements @@ -370,10 +367,23 @@ public: mContentDescription = aContentDescription; } + ViewID GetScrollId() const + { + return mScrollId; + } + + void SetScrollId(ViewID scrollId) + { + mScrollId = scrollId; + } + private: // New fields from now on should be made private and old fields should // be refactored to be private. + // A unique ID assigned to each scrollable frame. + ViewID mScrollId; + // The position of the top-left of the CSS viewport, relative to the document // (or the document relative to the viewport, if that helps understand it). // @@ -441,7 +451,7 @@ struct ScrollableLayerGuid { ScrollableLayerGuid(uint64_t aLayersId, const FrameMetrics& aMetrics) : mLayersId(aLayersId) , mPresShellId(aMetrics.mPresShellId) - , mScrollId(aMetrics.mScrollId) + , mScrollId(aMetrics.GetScrollId()) { MOZ_COUNT_CTOR(ScrollableLayerGuid); } diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index 78b1541edddf..52f8705d0ecf 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -121,7 +121,7 @@ AppendToString(nsACString& s, const FrameMetrics& m, AppendToString(s, m.GetScrollOffset(), " viewportScroll="); AppendToString(s, m.mDisplayPort, " displayport="); AppendToString(s, m.mScrollableRect, " scrollableRect="); - AppendToString(s, m.mScrollId, " scrollId=", " }"); + AppendToString(s, m.GetScrollId(), " scrollId=", " }"); return s += sfx; } diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp index c4dd7b5edefc..eccd247d9b9a 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.cpp +++ b/gfx/layers/client/ClientTiledThebesLayer.cpp @@ -72,7 +72,7 @@ ClientTiledThebesLayer::BeginPaint() ContainerLayer* scrollParent = nullptr; for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) { const FrameMetrics& metrics = parent->GetFrameMetrics(); - if (metrics.mScrollId != FrameMetrics::NULL_SCROLL_ID) { + if (metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) { scrollParent = parent; break; } diff --git a/gfx/layers/client/SimpleTiledContentClient.cpp b/gfx/layers/client/SimpleTiledContentClient.cpp index 493115c29171..fb902f928e67 100644 --- a/gfx/layers/client/SimpleTiledContentClient.cpp +++ b/gfx/layers/client/SimpleTiledContentClient.cpp @@ -284,7 +284,7 @@ SimpleClientTiledThebesLayer::BeginPaint() ContainerLayer* scrollParent = nullptr; for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) { const FrameMetrics& metrics = parent->GetFrameMetrics(); - if (metrics.mScrollId != FrameMetrics::NULL_SCROLL_ID) { + if (metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) { scrollParent = parent; break; } diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 12ab766765ee..54db3ac79803 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -156,7 +156,7 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics( const FrameMetrics& contentMetrics = aLayer->GetFrameMetrics(); FrameMetrics compositorMetrics; - if (!compositor->LookupCompositorFrameMetrics(contentMetrics.mScrollId, + if (!compositor->LookupCompositorFrameMetrics(contentMetrics.GetScrollId(), compositorMetrics)) { FindFallbackContentFrameMetrics(aLayer, aCompositionBounds, aZoom); return false; diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index bf37813e9c61..7679f3bdd327 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -211,7 +211,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, apzc->SetPrevSibling(nullptr); apzc->SetLastChild(nullptr); } - APZC_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().mScrollId); + APZC_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().GetScrollId()); apzc->NotifyLayersUpdated(metrics, aIsFirstPaint && (aLayersId == aFirstPaintLayersId)); diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index be57e1c68d11..cabcbc605d42 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -244,7 +244,7 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, bool isStickyForSubtree = aLayer->GetIsStickyPosition() && aTransformedSubtreeRoot->AsContainerLayer() && aLayer->GetStickyScrollContainerId() == - aTransformedSubtreeRoot->AsContainerLayer()->GetFrameMetrics().mScrollId; + aTransformedSubtreeRoot->AsContainerLayer()->GetFrameMetrics().GetScrollId(); if (aLayer != aTransformedSubtreeRoot && (isRootFixed || isStickyForSubtree)) { // Insert a translation so that the position of the anchor point is the same // before and after the change to the transform of aTransformedSubtreeRoot. @@ -606,7 +606,7 @@ AsyncCompositionManager::ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer) continue; } const FrameMetrics& metrics = scrollTarget->AsContainerLayer()->GetFrameMetrics(); - if (metrics.mScrollId != aLayer->GetScrollbarTargetContainerId()) { + if (metrics.GetScrollId() != aLayer->GetScrollbarTargetContainerId()) { continue; } if (!LayerHasNonContainerDescendants(scrollTarget->AsContainerLayer())) { diff --git a/gfx/layers/composite/ThebesLayerComposite.cpp b/gfx/layers/composite/ThebesLayerComposite.cpp index 68834bd31ad7..1a7845ee5278 100644 --- a/gfx/layers/composite/ThebesLayerComposite.cpp +++ b/gfx/layers/composite/ThebesLayerComposite.cpp @@ -182,7 +182,7 @@ ThebesLayerComposite::GetEffectiveResolution() { for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) { const FrameMetrics& metrics = parent->GetFrameMetrics(); - if (metrics.mScrollId != FrameMetrics::NULL_SCROLL_ID) { + if (metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) { return metrics.GetZoom(); } } diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 91e71bbf68d2..f5b5b65a76a4 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -69,7 +69,7 @@ " i=(%ld %lld) cb=(%d %d %d %d) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \ "s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \ __VA_ARGS__, \ - fm.mPresShellId, fm.mScrollId, \ + fm.mPresShellId, fm.GetScrollId(), \ fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \ fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \ fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \ @@ -325,7 +325,7 @@ static inline void LogRendertraceRect(const ScrollableLayerGuid& aGuid, const ch static const TimeStamp sRenderStart = TimeStamp::Now(); TimeDuration delta = TimeStamp::Now() - sRenderStart; printf_stderr("(%llu,%lu,%llu)%s RENDERTRACE %f rect %s %f %f %f %f\n", - aGuid.mLayersId, aGuid.mPresShellId, aGuid.mScrollId, + aGuid.mLayersId, aGuid.mPresShellId, aGuid.GetScrollId(), aDesc, delta.ToMilliseconds(), aColor, aRect.x, aRect.y, aRect.width, aRect.height); #endif @@ -480,7 +480,7 @@ AsyncPanZoomController::~AsyncPanZoomController() { // Only send the release message if the SharedFrameMetrics has been created. if (compositor && mSharedFrameMetricsBuffer) { - unused << compositor->SendReleaseSharedCompositorFrameMetrics(mFrameMetrics.mScrollId, mAPZCId); + unused << compositor->SendReleaseSharedCompositorFrameMetrics(mFrameMetrics.GetScrollId(), mAPZCId); } delete mSharedFrameMetricsBuffer; @@ -1778,7 +1778,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri // more "legitimate" sources like content scripts. nsRefPtr controller = GetGeckoContentController(); if (controller) { - controller->AcknowledgeScrollUpdate(aLayerMetrics.mScrollId, + controller->AcknowledgeScrollUpdate(aLayerMetrics.GetScrollId(), aLayerMetrics.GetScrollGeneration()); } } @@ -1989,10 +1989,10 @@ void AsyncPanZoomController::SetState(PanZoomState aNewState) { if (mGeckoContentController) { if (!IsTransformingState(oldState) && IsTransformingState(aNewState)) { mGeckoContentController->NotifyTransformBegin( - ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.mScrollId)); + ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId())); } else if (IsTransformingState(oldState) && !IsTransformingState(aNewState)) { mGeckoContentController->NotifyTransformEnd( - ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.mScrollId)); + ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId())); } } } diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index a8383d3466b1..049d7061f9e9 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -211,7 +211,7 @@ CompositorChild::SharedFrameMetricsData::GetViewID() MOZ_ASSERT(frame); // Not locking to read of mScrollId since it should not change after being // initially set. - return frame->mScrollId; + return frame->GetScrollId(); } uint32_t diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index c1818deba151..a07fcd2e172d 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -511,10 +511,10 @@ TEST(AsyncPanZoomController, ComplexTransform) { metrics.mResolution = ParentLayerToLayerScale(2); metrics.SetZoom(CSSToScreenScale(6)); metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3); - metrics.mScrollId = FrameMetrics::START_SCROLL_ID; + metrics.SetScrollId(FrameMetrics::START_SCROLL_ID); FrameMetrics childMetrics = metrics; - childMetrics.mScrollId = FrameMetrics::START_SCROLL_ID + 1; + childMetrics.SetScrollId(FrameMetrics::START_SCROLL_ID + 1); layers[0]->AsContainerLayer()->SetFrameMetrics(metrics); layers[1]->AsContainerLayer()->SetFrameMetrics(childMetrics); @@ -927,7 +927,7 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, { ContainerLayer* container = aLayer->AsContainerLayer(); FrameMetrics metrics; - metrics.mScrollId = aScrollId; + metrics.SetScrollId(aScrollId); nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds(); metrics.mCompositionBounds = ParentLayerIntRect(layerBound.x, layerBound.y, layerBound.width, layerBound.height); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 398a3e1df29c..7b1559cb2993 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -698,7 +698,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds); } - metrics.mScrollId = aScrollId; + metrics.SetScrollId(aScrollId); metrics.mIsRoot = aIsRoot; // Only the root scrollable frame for a given presShell should pick up diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index c6d4d61bfbc5..742a42a8a9e5 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -212,7 +212,7 @@ BuildListForLayer(Layer* aLayer, gfx3DMatrix transform; if (metrics && metrics->IsScrollable()) { - const ViewID scrollId = metrics->mScrollId; + const ViewID scrollId = metrics->GetScrollId(); // We need to figure out the bounds of the scrollable region using the // shadow layer tree from the remote process. The metrics viewport is @@ -280,7 +280,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, ViewTransform layerTransform = aTransform; if (metrics && metrics->IsScrollable()) { - const ViewID scrollId = metrics->mScrollId; + const ViewID scrollId = metrics->GetScrollId(); const nsContentView* view = aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId); NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree"); @@ -382,7 +382,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews, if (!container) return; const FrameMetrics metrics = container->GetFrameMetrics(); - const ViewID scrollId = metrics.mScrollId; + const ViewID scrollId = metrics.GetScrollId(); gfx3DMatrix transform; To3DMatrix(aLayer->GetTransform(), transform); aXScale *= GetXScale(transform); @@ -744,7 +744,7 @@ RenderFrameParent::Init(nsFrameLoader* aFrameLoader, } if (lm && lm->GetRoot() && lm->GetRoot()->AsContainerLayer()) { - ViewID rootScrollId = lm->GetRoot()->AsContainerLayer()->GetFrameMetrics().mScrollId; + ViewID rootScrollId = lm->GetRoot()->AsContainerLayer()->GetFrameMetrics().GetScrollId(); if (rootScrollId != FrameMetrics::NULL_SCROLL_ID) { mContentViews[rootScrollId] = new nsContentView(aFrameLoader, rootScrollId, true); } diff --git a/widget/gonk/ParentProcessController.cpp b/widget/gonk/ParentProcessController.cpp index 2464dbd5b2d1..ae85746714ec 100644 --- a/widget/gonk/ParentProcessController.cpp +++ b/widget/gonk/ParentProcessController.cpp @@ -24,7 +24,7 @@ public: NS_IMETHOD Run() { MOZ_ASSERT(NS_IsMainThread()); - nsCOMPtr content = nsLayoutUtils::FindContentFor(mFrameMetrics.mScrollId); + nsCOMPtr content = nsLayoutUtils::FindContentFor(mFrameMetrics.GetScrollId()); if (content) { APZCCallbackHelper::UpdateSubFrame(content, mFrameMetrics); } @@ -38,7 +38,7 @@ protected: void ParentProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics) { - if (aFrameMetrics.mScrollId == FrameMetrics::NULL_SCROLL_ID) { + if (aFrameMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) { return; } diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp index 31ec284cc55a..cb49038d452b 100644 --- a/widget/windows/winrt/APZController.cpp +++ b/widget/windows/winrt/APZController.cpp @@ -103,7 +103,7 @@ public: nsCOMPtr subDocument; nsCOMPtr targetContent; - if (!GetDOMTargets(mFrameMetrics.mScrollId, + if (!GetDOMTargets(mFrameMetrics.GetScrollId(), subDocument, targetContent)) { return NS_OK; } @@ -132,7 +132,7 @@ public: #ifdef DEBUG_CONTROLLER WinUtils::Log("APZController: %I64d mDisplayPort: %0.2f %0.2f %0.2f %0.2f", - mFrameMetrics.mScrollId, + mFrameMetrics.GetScrollId(), mFrameMetrics.mDisplayPort.x, mFrameMetrics.mDisplayPort.y, mFrameMetrics.mDisplayPort.width, @@ -205,7 +205,7 @@ APZController::RequestContentRepaint(const FrameMetrics& aFrameMetrics) #ifdef DEBUG_CONTROLLER WinUtils::Log("APZController::RequestContentRepaint scrollid=%I64d", - aFrameMetrics.mScrollId); + aFrameMetrics.GetScrollId()); #endif nsCOMPtr r1 = new RequestContentRepaintEvent(aFrameMetrics, mWidgetListener); diff --git a/widget/xpwidgets/APZCCallbackHelper.cpp b/widget/xpwidgets/APZCCallbackHelper.cpp index 77e942efaebd..c5c17789ba86 100644 --- a/widget/xpwidgets/APZCCallbackHelper.cpp +++ b/widget/xpwidgets/APZCCallbackHelper.cpp @@ -145,7 +145,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils, { // Precondition checks MOZ_ASSERT(aUtils); - if (aMetrics.mScrollId == FrameMetrics::NULL_SCROLL_ID) { + if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) { return; } @@ -160,7 +160,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils, aUtils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height); // Scroll the window to the desired spot - nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.mScrollId); + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId()); bool scrollUpdated = false; CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated); @@ -197,7 +197,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils, aUtils->SetResolution(presShellResolution.scale, presShellResolution.scale); // Finally, we set the displayport. - nsCOMPtr content = nsLayoutUtils::FindContentFor(aMetrics.mScrollId); + nsCOMPtr content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId()); if (!content) { return; } @@ -218,7 +218,7 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent, { // Precondition checks MOZ_ASSERT(aContent); - if (aMetrics.mScrollId == FrameMetrics::NULL_SCROLL_ID) { + if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) { return; } @@ -230,7 +230,7 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent, // We currently do not support zooming arbitrary subframes. They can only // be scrolled, so here we only have to set the scroll position and displayport. - nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.mScrollId); + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId()); bool scrollUpdated = false; CSSPoint actualScrollOffset = ScrollFrameTo(sf, aMetrics.GetScrollOffset(), scrollUpdated); @@ -334,7 +334,7 @@ DestroyCSSPoint(void* aObject, nsIAtom* aPropertyName, void APZCCallbackHelper::UpdateCallbackTransform(const FrameMetrics& aApzcMetrics, const FrameMetrics& aActualMetrics) { - nsCOMPtr content = nsLayoutUtils::FindContentFor(aApzcMetrics.mScrollId); + nsCOMPtr content = nsLayoutUtils::FindContentFor(aApzcMetrics.GetScrollId()); if (!content) { return; } From 44a69247e4cbd0f84fadfb558906e199d9c0bc28 Mon Sep 17 00:00:00 2001 From: Garrett Robinson Date: Fri, 21 Mar 2014 14:24:53 -0700 Subject: [PATCH 03/53] Bug 979580: Enable CSP 1.1 {nonce,hash}-source by default r=sstamm --- content/base/src/CSPUtils.jsm | 10 ---------- content/base/src/contentSecurityPolicy.js | 14 ++++++-------- content/base/test/csp/test_hash_source.html | 3 +-- content/base/test/csp/test_nonce_source.html | 3 +-- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/content/base/src/CSPUtils.jsm b/content/base/src/CSPUtils.jsm index bc4da2dd3b7c..d2aed262d3e4 100644 --- a/content/base/src/CSPUtils.jsm +++ b/content/base/src/CSPUtils.jsm @@ -1772,9 +1772,6 @@ this.CSPNonceSource = function CSPNonceSource() { } CSPNonceSource.fromString = function(aStr, aCSPRep) { - if (!CSPPrefObserver.experimentalEnabled) - return null; - let nonce = R_NONCESRC.exec(aStr)[1]; if (!nonce) { cspError(aCSPRep, "Error in parsing nonce-source from string: nonce was empty"); @@ -1789,8 +1786,6 @@ CSPNonceSource.fromString = function(aStr, aCSPRep) { CSPNonceSource.prototype = { permits: function(aContext) { - if (!CSPPrefObserver.experimentalEnabled) return false; - if (aContext instanceof Ci.nsIDOMHTMLElement) { return this._nonce === aContext.getAttribute('nonce'); } else if (typeof aContext === 'string') { @@ -1822,9 +1817,6 @@ this.CSPHashSource = function CSPHashSource() { } CSPHashSource.fromString = function(aStr, aCSPRep) { - if (!CSPPrefObserver.experimentalEnabled) - return null; - let hashSrcMatch = R_HASHSRC.exec(aStr); let algo = hashSrcMatch[1]; let hash = hashSrcMatch[2]; @@ -1846,8 +1838,6 @@ CSPHashSource.fromString = function(aStr, aCSPRep) { CSPHashSource.prototype = { permits: function(aContext) { - if (!CSPPrefObserver.experimentalEnabled) return false; - let ScriptableUnicodeConverter = Components.Constructor("@mozilla.org/intl/scriptableunicodeconverter", "nsIScriptableUnicodeConverter"); diff --git a/content/base/src/contentSecurityPolicy.js b/content/base/src/contentSecurityPolicy.js index 3911bc7ddc6f..99cf6197456c 100644 --- a/content/base/src/contentSecurityPolicy.js +++ b/content/base/src/contentSecurityPolicy.js @@ -208,9 +208,6 @@ ContentSecurityPolicy.prototype = { }, getAllowsNonce: function(aNonce, aContentType, shouldReportViolation) { - if (!CSPPrefObserver.experimentalEnabled) - return false; - if (!(aContentType == Ci.nsIContentPolicy.TYPE_SCRIPT || aContentType == Ci.nsIContentPolicy.TYPE_STYLESHEET)) { CSPdebug("Nonce check requested for an invalid content type (not script or style): " + aContentType); @@ -223,7 +220,9 @@ ContentSecurityPolicy.prototype = { shouldReportViolation.value = this._policies.some(function(policy, i) { // Don't report a violation if the policy didn't use nonce-source - return policy._directives[directive]._hasNonceSource && !policyAllowsNonce[i]; + return policy._directives.hasOwnProperty(directive) && + policy._directives[directive]._hasNonceSource && + !policyAllowsNonce[i]; }); // allow it to execute? (Do all the policies allow it to execute)? @@ -233,9 +232,6 @@ ContentSecurityPolicy.prototype = { }, getAllowsHash: function(aContent, aContentType, shouldReportViolation) { - if (!CSPPrefObserver.experimentalEnabled) - return false; - if (!(aContentType == Ci.nsIContentPolicy.TYPE_SCRIPT || aContentType == Ci.nsIContentPolicy.TYPE_STYLESHEET)) { CSPdebug("Hash check requested for an invalid content type (not script or style): " + aContentType); @@ -248,7 +244,9 @@ ContentSecurityPolicy.prototype = { shouldReportViolation.value = this._policies.some(function(policy, i) { // Don't report a violation if the policy didn't use hash-source - return policy._directives[directive]._hasHashSource && !policyAllowsHash[i]; + return policy._directives.hasOwnProperty(directive) && + policy._directives[directive]._hasHashSource && + !policyAllowsHash[i]; }); // allow it to execute? (Do all the policies allow it to execute)? diff --git a/content/base/test/csp/test_hash_source.html b/content/base/test/csp/test_hash_source.html index 46cfe7e45237..709ec761fe88 100644 --- a/content/base/test/csp/test_hash_source.html +++ b/content/base/test/csp/test_hash_source.html @@ -126,8 +126,7 @@ function checkInline () { SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv( - {'set':[["security.csp.speccompliant", true], - ["security.csp.experimentalEnabled", true]]}, + {'set':[["security.csp.speccompliant", true]]}, function() { // save this for last so that our listeners are registered. // ... this loads the testbed of good and bad requests. diff --git a/content/base/test/csp/test_nonce_source.html b/content/base/test/csp/test_nonce_source.html index 5360ea6859e9..892c4ee72909 100644 --- a/content/base/test/csp/test_nonce_source.html +++ b/content/base/test/csp/test_nonce_source.html @@ -113,8 +113,7 @@ window.examiner = new examiner(); SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv( - {'set':[["security.csp.speccompliant", true], - ["security.csp.experimentalEnabled", true]]}, + {'set':[["security.csp.speccompliant", true]]}, function() { // save this for last so that our listeners are registered. // ... this loads the testbed of good and bad requests. From 4d7ae1cfa3872e47f933cc566ff5b669e82c7a3b Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 04/53] Bug 986359 part 1 - Move SetTestSampleTime and LeaveTestMode to LayerTransactionParent; r=mattwoodrow --- dom/base/nsDOMWindowUtils.cpp | 19 ++++-- gfx/layers/ipc/CompositorParent.cpp | 78 ++++++++++++++--------- gfx/layers/ipc/CompositorParent.h | 6 +- gfx/layers/ipc/LayerTransactionParent.cpp | 13 ++++ gfx/layers/ipc/LayerTransactionParent.h | 2 + gfx/layers/ipc/PCompositor.ipdl | 6 -- gfx/layers/ipc/PLayerTransaction.ipdl | 7 ++ gfx/layers/ipc/ShadowLayersManager.h | 3 + 8 files changed, 90 insertions(+), 44 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 7579022cfcbf..7669d50f2ebf 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2554,9 +2554,13 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds) nsIWidget* widget = GetWidget(); if (widget) { - CompositorChild* compositor = widget->GetRemoteRenderer(); - if (compositor) { - compositor->SendSetTestSampleTime(driver->MostRecentRefresh()); + LayerManager* manager = widget->GetLayerManager(); + if (manager) { + ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); + if (forwarder && forwarder->HasShadowManager()) { + forwarder->GetShadowManager()->SendSetTestSampleTime( + driver->MostRecentRefresh()); + } } } @@ -2575,9 +2579,12 @@ nsDOMWindowUtils::RestoreNormalRefresh() // compositor. nsIWidget* widget = GetWidget(); if (widget) { - CompositorChild* compositor = widget->GetRemoteRenderer(); - if (compositor) { - compositor->SendLeaveTestMode(); + LayerManager* manager = widget->GetLayerManager(); + if (manager) { + ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); + if (forwarder && forwarder->HasShadowManager()) { + forwarder->GetShadowManager()->SendLeaveTestMode(); + } } } diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 1b699cc52285..407e34a69def 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -366,34 +366,6 @@ CompositorParent::RecvStopFrameTimeRecording(const uint32_t& aStartIndex, return true; } -bool -CompositorParent::RecvSetTestSampleTime(const TimeStamp& aTime) -{ - if (aTime.IsNull()) { - return false; - } - - mIsTesting = true; - mTestTime = aTime; - - // Update but only if we were already scheduled to animate - if (mCompositionManager && mCurrentCompositeTask) { - bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime); - if (!requestNextFrame) { - CancelCurrentCompositeTask(); - } - } - - return true; -} - -bool -CompositorParent::RecvLeaveTestMode() -{ - mIsTesting = false; - return true; -} - void CompositorParent::ActorDestroy(ActorDestroyReason why) { @@ -805,6 +777,34 @@ CompositorParent::ForceComposite(LayerTransactionParent* aLayerTree) ScheduleComposition(); } +bool +CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree, + const TimeStamp& aTime) +{ + if (aTime.IsNull()) { + return false; + } + + mIsTesting = true; + mTestTime = aTime; + + // Update but only if we were already scheduled to animate + if (mCompositionManager && mCurrentCompositeTask) { + bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime); + if (!requestNextFrame) { + CancelCurrentCompositeTask(); + } + } + + return true; +} + +void +CompositorParent::LeaveTestMode(LayerTransactionParent* aLayerTree) +{ + mIsTesting = false; +} + void CompositorParent::InitializeLayerManager(const nsTArray& aBackendHints) { @@ -1067,8 +1067,6 @@ public: virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) { return true; } virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) MOZ_OVERRIDE { return true; } virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray* intervals) MOZ_OVERRIDE { return true; } - virtual bool RecvSetTestSampleTime(const TimeStamp& aTime) MOZ_OVERRIDE { return true; } - virtual bool RecvLeaveTestMode() MOZ_OVERRIDE { return true; } virtual PLayerTransactionParent* AllocPLayerTransactionParent(const nsTArray& aBackendHints, @@ -1083,6 +1081,9 @@ public: bool aIsFirstPaint, bool aScheduleComposite) MOZ_OVERRIDE; virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; + virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, + const TimeStamp& aTime) MOZ_OVERRIDE; + virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) MOZ_OVERRIDE; @@ -1243,6 +1244,23 @@ CrossProcessCompositorParent::ForceComposite(LayerTransactionParent* aLayerTree) sIndirectLayerTrees[id].mParent->ForceComposite(aLayerTree); } +bool +CrossProcessCompositorParent::SetTestSampleTime( + LayerTransactionParent* aLayerTree, const TimeStamp& aTime) +{ + uint64_t id = aLayerTree->GetId(); + MOZ_ASSERT(id != 0); + return sIndirectLayerTrees[id].mParent->SetTestSampleTime(aLayerTree, aTime); +} + +void +CrossProcessCompositorParent::LeaveTestMode(LayerTransactionParent* aLayerTree) +{ + uint64_t id = aLayerTree->GetId(); + MOZ_ASSERT(id != 0); + sIndirectLayerTrees[id].mParent->LeaveTestMode(aLayerTree); +} + AsyncCompositionManager* CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLayerTree) { diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 8509d2e4a258..25b7ebb61c17 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -92,8 +92,6 @@ public: virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) MOZ_OVERRIDE; virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) MOZ_OVERRIDE; virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray* intervals) MOZ_OVERRIDE; - virtual bool RecvSetTestSampleTime(const TimeStamp& aTime) MOZ_OVERRIDE; - virtual bool RecvLeaveTestMode() MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; @@ -102,7 +100,11 @@ public: bool aIsFirstPaint, bool aScheduleComposite) MOZ_OVERRIDE; virtual void ForceComposite(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; + virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, + const TimeStamp& aTime) MOZ_OVERRIDE; + virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE; virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) MOZ_OVERRIDE { return mCompositionManager; } + /** * This forces the is-first-paint flag to true. This is intended to * be called by the widget code when it loses its viewport information diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 051c31dd30b5..835296fc23b7 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -559,6 +559,19 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray& cset, return true; } +bool +LayerTransactionParent::RecvSetTestSampleTime(const TimeStamp& aTime) +{ + return mShadowLayersManager->SetTestSampleTime(this, aTime); +} + +bool +LayerTransactionParent::RecvLeaveTestMode() +{ + mShadowLayersManager->LeaveTestMode(this); + return true; +} + bool LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent, float* aOpacity) diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 23f53050d88e..422e973c372d 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -93,6 +93,8 @@ protected: virtual bool RecvClearCachedResources() MOZ_OVERRIDE; virtual bool RecvForceComposite() MOZ_OVERRIDE; + virtual bool RecvSetTestSampleTime(const TimeStamp& aTime) MOZ_OVERRIDE; + virtual bool RecvLeaveTestMode() MOZ_OVERRIDE; virtual bool RecvGetOpacity(PLayerParent* aParent, float* aOpacity) MOZ_OVERRIDE; virtual bool RecvGetAnimationTransform(PLayerParent* aParent, diff --git a/gfx/layers/ipc/PCompositor.ipdl b/gfx/layers/ipc/PCompositor.ipdl index 3a8f8678b552..05d1b33bc9c5 100644 --- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -75,12 +75,6 @@ parent: sync StopFrameTimeRecording(uint32_t startIndex) returns (float[] intervals); - // Enter test mode, set the sample time to sampleTime, and resample animations. - // sampleTime must not be null. - sync SetTestSampleTime(TimeStamp sampleTime); - // Leave test mode and resume normal compositing - sync LeaveTestMode(); - // layersBackendHints is an ordered list of preffered backends where // layersBackendHints[0] is the best backend. If any hints are LayersBackend::LAYERS_NONE // that hint is ignored. diff --git a/gfx/layers/ipc/PLayerTransaction.ipdl b/gfx/layers/ipc/PLayerTransaction.ipdl index e866b37f1818..a6453c372d9f 100644 --- a/gfx/layers/ipc/PLayerTransaction.ipdl +++ b/gfx/layers/ipc/PLayerTransaction.ipdl @@ -82,6 +82,13 @@ parent: returns (EditReply[] reply); // Testing APIs + + // Enter test mode, set the sample time to sampleTime, and resample + // animations. sampleTime must not be null. + sync SetTestSampleTime(TimeStamp sampleTime); + // Leave test mode and resume normal compositing + sync LeaveTestMode(); + sync GetOpacity(PLayer layer) returns (float opacity); // Returns the value of the transform applied to the layer by animation after diff --git a/gfx/layers/ipc/ShadowLayersManager.h b/gfx/layers/ipc/ShadowLayersManager.h index ddaddbc92b47..95566682dd54 100644 --- a/gfx/layers/ipc/ShadowLayersManager.h +++ b/gfx/layers/ipc/ShadowLayersManager.h @@ -25,6 +25,9 @@ public: virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aLayerTree) { return nullptr; } virtual void ForceComposite(LayerTransactionParent* aLayerTree) { } + virtual bool SetTestSampleTime(LayerTransactionParent* aLayerTree, + const TimeStamp& aTime) { return true; } + virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { } }; } // layers From d961380bc0c7ffcc7a9e06e571c78f1de47f54b0 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 05/53] Bug 986359 part 2 - Factor out GetTransaction in DOMWindowUtils; r=mattwoodrow --- dom/base/nsDOMWindowUtils.cpp | 42 +++++++++++++++++++---------------- dom/base/nsDOMWindowUtils.h | 7 ++++++ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 7669d50f2ebf..5ca7f086c895 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -162,6 +162,23 @@ nsDOMWindowUtils::GetDocument() return window->GetExtantDoc(); } +LayerTransactionChild* +nsDOMWindowUtils::GetLayerTransaction() +{ + nsIWidget* widget = GetWidget(); + if (!widget) + return nullptr; + + LayerManager* manager = widget->GetLayerManager(); + if (!manager) + return nullptr; + + ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); + return forwarder && forwarder->HasShadowManager() ? + forwarder->GetShadowManager() : + nullptr; +} + NS_IMETHODIMP nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode) { @@ -2552,16 +2569,9 @@ nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds) nsRefreshDriver* driver = GetPresContext()->RefreshDriver(); driver->AdvanceTimeAndRefresh(aMilliseconds); - nsIWidget* widget = GetWidget(); - if (widget) { - LayerManager* manager = widget->GetLayerManager(); - if (manager) { - ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); - if (forwarder && forwarder->HasShadowManager()) { - forwarder->GetShadowManager()->SendSetTestSampleTime( - driver->MostRecentRefresh()); - } - } + LayerTransactionChild* transaction = GetLayerTransaction(); + if (transaction) { + transaction->SendSetTestSampleTime(driver->MostRecentRefresh()); } return NS_OK; @@ -2577,15 +2587,9 @@ nsDOMWindowUtils::RestoreNormalRefresh() // Kick the compositor out of test mode before the refresh driver, so that // the refresh driver doesn't send an update that gets ignored by the // compositor. - nsIWidget* widget = GetWidget(); - if (widget) { - LayerManager* manager = widget->GetLayerManager(); - if (manager) { - ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); - if (forwarder && forwarder->HasShadowManager()) { - forwarder->GetShadowManager()->SendLeaveTestMode(); - } - } + LayerTransactionChild* transaction = GetLayerTransaction(); + if (transaction) { + transaction->SendLeaveTestMode(); } nsRefreshDriver* driver = GetPresContext()->RefreshDriver(); diff --git a/dom/base/nsDOMWindowUtils.h b/dom/base/nsDOMWindowUtils.h index 3cb32cb3b9ce..68f26638f154 100644 --- a/dom/base/nsDOMWindowUtils.h +++ b/dom/base/nsDOMWindowUtils.h @@ -19,6 +19,12 @@ class nsPresContext; class nsPoint; class nsIDocument; +namespace mozilla { + namespace layers { + class LayerTransactionChild; + } +} + class nsDOMWindowUtils MOZ_FINAL : public nsIDOMWindowUtils, public nsSupportsWeakReference { @@ -41,6 +47,7 @@ protected: nsIPresShell* GetPresShell(); nsPresContext* GetPresContext(); nsIDocument* GetDocument(); + mozilla::layers::LayerTransactionChild* GetLayerTransaction(); NS_IMETHOD SendMouseEventCommon(const nsAString& aType, float aX, From bd02c4b352969d284cc019a64785a313e575f1ad Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 06/53] Bug 986359 part 3 - Add AutoResolveRefLayers before calling TransformShadowTree; r=mattwoodrow --- gfx/layers/ipc/CompositorParent.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 407e34a69def..35e4daeabfec 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -761,6 +761,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, // scheduled in order to better match the behavior under regular sampling // conditions. if (mIsTesting && root && mCurrentCompositeTask) { + AutoResolveRefLayers resolve(mCompositionManager); bool requestNextFrame = mCompositionManager->TransformShadowTree(mTestTime); if (!requestNextFrame) { @@ -790,6 +791,7 @@ CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree, // Update but only if we were already scheduled to animate if (mCompositionManager && mCurrentCompositeTask) { + AutoResolveRefLayers resolve(mCompositionManager); bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime); if (!requestNextFrame) { CancelCurrentCompositeTask(); From 4348ab37689d792571c660b25185c51f5dcd8786 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 07/53] Bug 975261 part 1 - Add test for OMTA animations that start with a delay; r=dzbarsky --- layout/style/test/mochitest.ini | 1 + .../test/test_animations_omta_start.html | 77 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 layout/style/test/test_animations_omta_start.html diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index 2a06dba24544..f1ad3e9f9602 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -34,6 +34,7 @@ generated-files = css_properties.js [test_all_shorthand.html] [test_animations.html] skip-if = toolkit == 'android' +[test_animations_omta_start.html] [test_any_dynamic.html] [test_at_rule_parse_serialize.html] [test_bug73586.html] diff --git a/layout/style/test/test_animations_omta_start.html b/layout/style/test/test_animations_omta_start.html new file mode 100644 index 000000000000..f04e91ed18cb --- /dev/null +++ b/layout/style/test/test_animations_omta_start.html @@ -0,0 +1,77 @@ + + + + + + Test OMTA animations start correctly (Bug 975261) + + + + + + +Mozilla Bug + 975261 +
+
+
+
+ + From 97f46c1cf21f199f5bcbe0a22b92bb25cc679a7d Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 08/53] Bug 975261 part 2 - Trigger animations with a delay; r=dzbarsky Animations with a delay are not put on the compositor thread until the end of the delay phase. However, there is currently nothing that explicitly triggers this transaction. It may occur due to flushes that arise from UI events but it is not guaranteed. This patch detects the end of a delay phase and turns off throttling for that sample. It re-uses the mLastNotification member which is not ideal but a subsequent patch in this queue removes this and replaces it with the approach used for transitions. --- layout/style/nsAnimationManager.cpp | 5 +++-- layout/style/test/test_animations_omta_start.html | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 68dccce43dbc..975aee4ca7eb 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -203,8 +203,9 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime, // indicator that the animation has finished, it should be reserved for // events. If we use it differently in the future this use might need // changing. - if (anim.mLastNotification == ElementAnimation::LAST_NOTIFICATION_END && - anim.mLastNotification != oldLastNotification) { + if (anim.mLastNotification != oldLastNotification && + (anim.mLastNotification == ElementAnimation::LAST_NOTIFICATION_END || + anim.mLastNotification == 0)) { aIsThrottled = false; break; } diff --git a/layout/style/test/test_animations_omta_start.html b/layout/style/test/test_animations_omta_start.html index f04e91ed18cb..d8602401fbf4 100644 --- a/layout/style/test/test_animations_omta_start.html +++ b/layout/style/test/test_animations_omta_start.html @@ -62,8 +62,8 @@ function testDelay() { waitForAllPaints(function() { var opacity = SpecialPowers.DOMWindowUtils.getOMTAStyle(target, "opacity"); - todo_is(opacity, 0.5, - "opacity is set on compositor thread after delayed start"); + is(opacity, 0.5, + "opacity is set on compositor thread after delayed start"); target.removeAttribute("style"); SpecialPowers.DOMWindowUtils.restoreNormalRefresh(); SimpleTest.finish(); From 0750783e1bd177ccc75d49e40ac0e28cb9182f60 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Sat, 22 Mar 2014 05:59:57 +0800 Subject: [PATCH 09/53] Bug 975261 part 3 - Add test for transforms; r=dzbarsky Adds a test for transform animations with a delay where there is already a transform specified on the element. This test used to fail but bug 828173 fixed it. It is included here as a regression test. (Prior to bug 828173 we were able to fix this by triggering ForceLayerRerendering inside nsAnimationManager::nsFlushAnimations whenever we detected *different* style rules but canThrottleTick=true) The issue stemmed from the fact that when an element has a transform property, LayerIsPrerenderedDataKey would get set on the layer because in nsDisplayTransform::ShouldPrerenderTransformedContent we would only check for the *presence* of an animation, not whether it is running. Then in RestyleManager::DoApplyRenderingChangeToTree we wouldn't do an invalidating paint because TryUpdateTransformOnly() returns true since it looks at LayerIsPrerenderedDataKey. Bug 828173 fixes this, at least in part, by checking if an animation is running. This bug may resurface if we put animations with a delay on the compositor thread hence it is worth including here. --- .../test/test_animations_omta_start.html | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/layout/style/test/test_animations_omta_start.html b/layout/style/test/test_animations_omta_start.html index d8602401fbf4..987e8e8930f6 100644 --- a/layout/style/test/test_animations_omta_start.html +++ b/layout/style/test/test_animations_omta_start.html @@ -12,12 +12,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=975261 src="/tests/SimpleTest/paint_listener.js">