From 1f7853ecd1666ef4a268ee131b92477681122079 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 30 Oct 2013 15:58:25 -0400 Subject: [PATCH 01/13] Bug 932525 - Do APZC hit testing using the layer's screen coordinates rather than layer coordinates. r=kats --- gfx/layers/composite/APZCTreeManager.cpp | 44 ++-- gfx/layers/ipc/AsyncPanZoomController.h | 13 +- .../gtest/TestAsyncPanZoomController.cpp | 219 ++++++++++++------ 3 files changed, 181 insertions(+), 95 deletions(-) diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 56ba7d6942c..974c16e35de 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -141,7 +141,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, apzc->NotifyLayersUpdated(container->GetFrameMetrics(), aIsFirstPaint && (aLayersId == aFirstPaintLayersId)); - LayerRect visible = ScreenRect(container->GetFrameMetrics().mCompositionBounds) * ScreenToLayerScale(1.0); + ScreenRect visible(container->GetFrameMetrics().mCompositionBounds); apzc->SetLayerHitTestData(visible, aTransform, aLayer->GetTransform()); APZC_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y, visible.width, visible.height, @@ -629,30 +629,42 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a // comments explain what values are stored in the variables at these two levels. All the comments // use standard matrix notation where the leftmost matrix in a multiplication is applied first. - // ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L, - // and RC.Inverse() * QC.Inverse() at recursion level for P. + // ancestorUntransform takes points from aApzc's parent APZC's screen coordinates + // to aApzc's screen coordinates. + // It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L, + // and RC.Inverse() * QC.Inverse() at recursion level for P. gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse(); - // asyncUntransform is LA.Inverse() at recursion level for L, - // and PA.Inverse() at recursion level for P. - gfx3DMatrix asyncUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse(); - // untransformSinceLastApzc is OC.Inverse() * NC.Inverse() * MC.Inverse() * LA.Inverse() * LC.Inverse() at L, - // and RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() at P. - gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * asyncUntransform * aApzc->GetCSSTransform().Inverse(); - // untransformed is the user input in L's layer space at L, - // and in P's layer space at P. - gfxPoint untransformed = untransformSinceLastApzc.ProjectPoint(aHitTestPoint); - APZC_LOG("Untransformed %f %f to %f %f for APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, untransformed.x, untransformed.y, aApzc); + + // Hit testing for this layer is performed in aApzc's screen coordinates. + gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint); + APZC_LOG("Untransformed %f %f to screen coordinates %f %f for hit-testing APZC %p\n", + aHitTestPoint.x, aHitTestPoint.y, + hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc); + + // myUntransform takes points from aApzc's screen coordinates + // to aApzc's layer coordinates (which are aApzc's children's screen coordinates). + // It is LA.Inverse() * LC.Inverse() at L + // and PA.Inverse() * PC.Inverse() at P. + gfx3DMatrix myUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse() + * aApzc->GetCSSTransform().Inverse(); + + // Hit testing for child layers is performed in aApzc's layer coordinates. + gfxPoint hitTestPointForChildLayers = myUntransform.ProjectPoint(hitTestPointForThisLayer); + APZC_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n", + aHitTestPoint.x, aHitTestPoint.y, + hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc); // This walks the tree in depth-first, reverse order, so that it encounters // APZCs front-to-back on the screen. for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) { - AsyncPanZoomController* match = GetAPZCAtPoint(child, untransformed); + AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers); if (match) { return match; } } - if (aApzc->VisibleRegionContains(LayerPoint(untransformed.x, untransformed.y))) { - APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n", untransformed.x, untransformed.y, aApzc); + if (aApzc->VisibleRegionContains(ScreenPoint(hitTestPointForThisLayer.x, hitTestPointForThisLayer.y))) { + APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n", + hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc); return aApzc; } return nullptr; diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index 4c1906a4c4c..82c6be9b25d 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -655,7 +655,7 @@ private: * hit-testing to see which APZC instance should handle touch events. */ public: - void SetLayerHitTestData(const LayerRect& aRect, const gfx3DMatrix& aTransformToLayer, + void SetLayerHitTestData(const ScreenRect& aRect, const gfx3DMatrix& aTransformToLayer, const gfx3DMatrix& aTransformForLayer) { mVisibleRect = aRect; mAncestorTransform = aTransformToLayer; @@ -670,16 +670,15 @@ public: return mCSSTransform; } - bool VisibleRegionContains(const LayerPoint& aPoint) const { + bool VisibleRegionContains(const ScreenPoint& aPoint) const { return mVisibleRect.Contains(aPoint); } private: - /* This is the viewport of the layer that this APZC corresponds to, in - * layer pixels. It position here does not account for any transformations - * applied to any layers, whether they are CSS transforms or async - * transforms. */ - LayerRect mVisibleRect; + /* This is the visible region of the layer that this APZC corresponds to, in + * that layer's screen pixels (the same coordinate system in which this APZC + * receives events in ReceiveInputEvent()). */ + ScreenRect mVisibleRect; /* This is the cumulative CSS transform for all the layers between the parent * APZC and this one (not inclusive) */ gfx3DMatrix mAncestorTransform; diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index e1ec6477760..6283afa6638 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -433,19 +433,17 @@ TEST(AsyncPanZoomController, OverScrollPanning) { EXPECT_EQ(pointOut, ScreenPoint(0, 90)); } +// Layer tree for HitTesting1 static already_AddRefed -CreateTestLayerTree(nsRefPtr& aLayerManager, nsTArray >& aLayers) { - const char* layerTreeSyntax = "c(ttccc(c(c)))"; - // LayerID 0 12345 6 7 +CreateTestLayerTree1(nsRefPtr& aLayerManager, nsTArray >& aLayers) { + const char* layerTreeSyntax = "c(ttcc)"; + // LayerID 0 1234 nsIntRegion layerVisibleRegion[] = { nsIntRegion(nsIntRect(0,0,100,100)), nsIntRegion(nsIntRect(0,0,100,100)), nsIntRegion(nsIntRect(10,10,20,20)), nsIntRegion(nsIntRect(10,10,20,20)), nsIntRegion(nsIntRect(5,5,20,20)), - nsIntRegion(nsIntRect(10,10,40,40)), - nsIntRegion(nsIntRect(10,10,40,40)), - nsIntRegion(nsIntRect(10,10,40,40)), }; gfx3DMatrix transforms[] = { gfx3DMatrix(), @@ -453,15 +451,35 @@ CreateTestLayerTree(nsRefPtr& aLayerManager, nsTArray +CreateTestLayerTree2(nsRefPtr& aLayerManager, nsTArray >& aLayers) { + const char* layerTreeSyntax = "c(cc(c))"; + // LayerID 0 12 3 + nsIntRegion layerVisibleRegion[] = { + nsIntRegion(nsIntRect(0,0,100,100)), + nsIntRegion(nsIntRect(10,10,40,40)), + nsIntRegion(nsIntRect(10,60,40,40)), + nsIntRegion(nsIntRect(10,60,40,40)), + }; + gfx3DMatrix transforms[] = { + gfx3DMatrix(), + gfx3DMatrix(), + gfx3DMatrix(), + gfx3DMatrix(), }; return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers); } static void -SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, MockContentController* mcc) +SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, + // The scrollable rect is only used in HitTesting2, + // HitTesting1 doesn't care about it. + CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) { ContainerLayer* container = aLayer->AsContainerLayer(); FrameMetrics metrics; @@ -469,8 +487,8 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, MockCon nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds(); metrics.mCompositionBounds = ScreenIntRect(layerBound.x, layerBound.y, layerBound.width, layerBound.height); - metrics.mViewport = CSSRect(layerBound.x, layerBound.y, - layerBound.width, layerBound.height); + metrics.mScrollableRect = aScrollableRect; + metrics.mScrollOffset = CSSPoint(0, 0); container->SetFrameMetrics(metrics); } @@ -499,10 +517,11 @@ GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint, return hit.forget(); } -TEST(APZCTreeManager, GetAPZCAtPoint) { +// A simple hit testing test that doesn't involve any transforms on layers. +TEST(APZCTreeManager, HitTesting1) { nsTArray > layers; nsRefPtr lm; - nsRefPtr root = CreateTestLayerTree(lm, layers); + nsRefPtr root = CreateTestLayerTree1(lm, layers); TimeStamp testStartTime = TimeStamp::Now(); AsyncPanZoomController::SetFrameTime(testStartTime); @@ -521,8 +540,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { EXPECT_EQ(gfx3DMatrix(), transformToScreen); // Now we have a root APZC that will match the page - SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); + SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) @@ -530,8 +549,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { EXPECT_EQ(gfxPoint(15, 15), transformToScreen.Transform(gfxPoint(15, 15))); // Now we have a sub APZC with a better fit - SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); + SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController()); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); @@ -542,8 +561,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { // Now test hit testing when we have two scrollable layers hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); - SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1, mcc); - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); + SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1); + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) @@ -567,59 +586,115 @@ TEST(APZCTreeManager, GetAPZCAtPoint) { EXPECT_EQ(gfx3DMatrix(), transformToApzc); EXPECT_EQ(gfx3DMatrix(), transformToScreen); - // Test layer transform - gfx3DMatrix transform; - transform.ScalePost(0.1, 0.1, 1); - root->SetBaseTransform(transform); - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); - hit = GetTargetAPZC(manager, ScreenPoint(50, 50), transformToApzc, transformToScreen); // This point is now outside the root layer - EXPECT_EQ(nullAPZC, hit.get()); - EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToScreen); - - // This hit test will hit both layers[3] and layers[4]; layers[4] is later in the tree so - // it is a better match - hit = GetTargetAPZC(manager, ScreenPoint(2, 2), transformToApzc, transformToScreen); - EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); - // expect hit point at LayerPoint(20, 20) - EXPECT_EQ(gfxPoint(20, 20), NudgeToIntegers(transformToApzc.Transform(gfxPoint(2, 2)))); - EXPECT_EQ(gfxPoint(2, 2), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 20)))); - - // Scale layer[4] outside the range - layers[4]->SetBaseTransform(transform); - // layer 4 effective visible screenrect: (0.05, 0.05, 0.2, 0.2) - // Does not contain (2, 2) - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); - hit = GetTargetAPZC(manager, ScreenPoint(2, 2), transformToApzc, transformToScreen); - EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); - // expect hit point at LayerPoint(20, 20) - EXPECT_EQ(gfxPoint(20, 20), NudgeToIntegers(transformToApzc.Transform(gfxPoint(2, 2)))); - EXPECT_EQ(gfxPoint(2, 2), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 20)))); - - // Transformation chain to layer 7 - SetScrollableFrameMetrics(layers[7], FrameMetrics::START_SCROLL_ID + 2, mcc); - - gfx3DMatrix translateTransform; - translateTransform.Translate(gfxPoint3D(10, 10, 0)); - layers[5]->SetBaseTransform(translateTransform); - - gfx3DMatrix translateTransform2; - translateTransform2.Translate(gfxPoint3D(-20, 0, 0)); - layers[6]->SetBaseTransform(translateTransform2); - - gfx3DMatrix translateTransform3; - translateTransform3.ScalePost(1,15,1); - layers[7]->SetBaseTransform(translateTransform3); - - manager->UpdatePanZoomControllerTree(nullptr, root, 0, false); - // layer 7 effective visible screenrect (0,16,4,60) but clipped by parent layers - hit = GetTargetAPZC(manager, ScreenPoint(1, 45), transformToApzc, transformToScreen); - EXPECT_EQ(layers[7]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); - // expect hit point at LayerPoint(20, 440), which is CSSPoint(20, 29) - EXPECT_EQ(gfxPoint(20, 440), NudgeToIntegers(transformToApzc.Transform(gfxPoint(1, 45)))); - EXPECT_EQ(gfxPoint(1, 45), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 440)))); - manager->ClearTree(); } +// A more involved hit testing test that involves css and async transforms. +TEST(APZCTreeManager, HitTesting2) { + nsTArray > layers; + nsRefPtr lm; + nsRefPtr root = CreateTestLayerTree2(lm, layers); + TimeStamp testStartTime = TimeStamp::Now(); + AsyncPanZoomController::SetFrameTime(testStartTime); + nsRefPtr mcc = new MockContentController(); + ScopedLayerTreeRegistration controller(0, root, mcc); + + nsRefPtr manager = new TestAPZCTreeManager(); + nsRefPtr hit; + gfx3DMatrix transformToApzc; + gfx3DMatrix transformToScreen; + + // Set a CSS transform on one of the layers. + gfx3DMatrix transform; + transform.ScalePost(2, 1, 1); + layers[2]->SetBaseTransform(transform); + + // Make some other layers scrollable. + SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, CSSRect(0, 0, 200, 200)); + SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 80, 80)); + SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80)); + + manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); + + // At this point, the following holds (all coordinates in screen pixels): + // layers[0] has content from (0,0)-(200,200), clipped by composition bounds (0,0)-(100,100) + // layers[1] has content from (10,10)-(90,90), clipped by composition bounds (10,10)-(50,50) + // layers[2] has content from (20,60)-(100,100). no clipping as it's not a scrollable layer + // layers[3] has content from (20,60)-(180,140), clipped by composition bounds (20,60)-(100,100) + + AsyncPanZoomController* apzcroot = root->AsContainerLayer()->GetAsyncPanZoomController(); + AsyncPanZoomController* apzc1 = layers[1]->AsContainerLayer()->GetAsyncPanZoomController(); + AsyncPanZoomController* apzc3 = layers[3]->AsContainerLayer()->GetAsyncPanZoomController(); + + // Hit an area that's clearly on the root layer but not any of the child layers. + hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToScreen); + EXPECT_EQ(apzcroot, hit.get()); + EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25))); + EXPECT_EQ(gfxPoint(75, 25), transformToScreen.Transform(gfxPoint(75, 25))); + + // Hit an area on the root that would be on layers[3] if layers[2] + // weren't transformed. + // Note that if layers[2] were scrollable, then this would hit layers[2] + // because its composition bounds would be at (10,60)-(50,100) (and the + // scale-only transform that we set on layers[2] would be invalid because + // it would place the layer into overscroll, as its composition bounds + // start at x=10 but its content at x=20). + hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToScreen); + EXPECT_EQ(apzcroot, hit.get()); + EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75))); + EXPECT_EQ(gfxPoint(15, 75), transformToScreen.Transform(gfxPoint(15, 75))); + + // Hit an area on layers[1]. + hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen); + EXPECT_EQ(apzc1, hit.get()); + EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25))); + EXPECT_EQ(gfxPoint(25, 25), transformToScreen.Transform(gfxPoint(25, 25))); + + // Hit an area on layers[3]. + hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToScreen); + EXPECT_EQ(apzc3, hit.get()); + // transformToApzc should unapply layers[2]'s transform + EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75))); + // and transformToScreen should reapply it + EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75))); + + // Hit an area on layers[3] that would be on the root if layers[2] + // weren't transformed. + hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen); + EXPECT_EQ(apzc3, hit.get()); + // transformToApzc should unapply layers[2]'s transform + EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75))); + // and transformToScreen should reapply it + EXPECT_EQ(gfxPoint(75, 75), transformToScreen.Transform(gfxPoint(37.5, 75))); + + // Pan the root layer upward by 50 pixels. + // This causes layers[1] to scroll out of view, and an async transform + // of -50 to be set on the root layer. + int time = 0; + // Silence GMock warnings about "uninteresting mock function calls". + EXPECT_CALL(*mcc, PostDelayedTask(_,_)).Times(1); + EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(2); + EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1); + ApzcPan(apzcroot, time, 100, 50); + + // Hit where layers[3] used to be. It should now hit the root. + hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen); + EXPECT_EQ(apzcroot, hit.get()); + // transformToApzc doesn't unapply the root's own async transform + EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75))); + // but transformToScreen does + EXPECT_EQ(gfxPoint(75, 125), transformToScreen.Transform(gfxPoint(75, 75))); + + // Hit where layers[1] used to be and where layers[3] should now be. + hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen); + EXPECT_EQ(apzc3, hit.get()); + // transformToApzc unapplies both layers[2]'s css transform and the root's + // async trasnform + EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25))); + // transformToScreen reapplies the css transform only (since Gecko doesn't + // know about async transforms) + EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75))); + + manager->ClearTree(); +} \ No newline at end of file From 42c1f6350b9ebd6c103c9da1325902cb2fbf5656 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Thu, 31 Oct 2013 14:44:33 -0400 Subject: [PATCH 02/13] Bug 932525 - Better naming for some transformation matrix variables. r=kats --- gfx/layers/composite/APZCTreeManager.cpp | 56 +++++++------- gfx/layers/composite/APZCTreeManager.h | 2 +- .../gtest/TestAsyncPanZoomController.cpp | 76 +++++++++---------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index 974c16e35de..a9aaec77a0a 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -233,7 +233,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) { nsEventStatus result = nsEventStatus_eIgnore; gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; + gfx3DMatrix transformToGecko; switch (aEvent.mInputType) { case MULTITOUCH_INPUT: { const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput(); @@ -251,7 +251,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) // Cache transformToApzc so it can be used for future events in this block. if (mApzcForInputBlock) { - GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToScreen); + GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko); mCachedTransformToApzcForInputBlock = transformToApzc; } } else if (mApzcForInputBlock) { @@ -279,7 +279,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) const PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput(); nsRefPtr apzc = GetTargetAPZC(pinchInput.mFocusPoint); if (apzc) { - GetInputTransforms(apzc, transformToApzc, transformToScreen); + GetInputTransforms(apzc, transformToApzc, transformToGecko); PinchGestureInput inputForApzc(pinchInput); ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc); result = apzc->ReceiveInputEvent(inputForApzc); @@ -289,7 +289,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent) const TapGestureInput& tapInput = aEvent.AsTapGestureInput(); nsRefPtr apzc = GetTargetAPZC(ScreenPoint(tapInput.mPoint)); if (apzc) { - GetInputTransforms(apzc, transformToApzc, transformToScreen); + GetInputTransforms(apzc, transformToApzc, transformToGecko); TapGestureInput inputForApzc(tapInput); ApplyTransform(&(inputForApzc.mPoint), transformToApzc); result = apzc->ReceiveInputEvent(inputForApzc); @@ -305,7 +305,7 @@ APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, ScreenPoint aPoint) { nsRefPtr apzc = GetTargetAPZC(aPoint); - gfx3DMatrix transformToApzc, transformToScreen; + gfx3DMatrix transformToApzc, transformToGecko; // Reset the cached apz transform mCachedTransformToApzcForInputBlock = transformToApzc; if (!apzc) { @@ -324,7 +324,7 @@ APZCTreeManager::GetTouchInputBlockAPZC(const WidgetTouchEvent& aEvent, } if (apzc) { // Cache apz transform so it can be used for future events in this block. - GetInputTransforms(apzc, mCachedTransformToApzcForInputBlock, transformToScreen); + GetInputTransforms(apzc, mCachedTransformToApzcForInputBlock, transformToGecko); } return apzc.get(); } @@ -344,11 +344,11 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent, nsEventStatus ret = mApzcForInputBlock->ReceiveInputEvent(inputForApzc); // For computing the event to pass back to Gecko, use the up-to-date transforms. - // This ensures that transformToApzc and transformToScreen are in sync - // (note that transformToScreen isn't cached). - gfx3DMatrix transformToScreen; - GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToScreen); - gfx3DMatrix outTransform = transformToApzc * transformToScreen; + // This ensures that transformToApzc and transformToGecko are in sync + // (note that transformToGecko isn't cached). + gfx3DMatrix transformToGecko; + GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko); + gfx3DMatrix outTransform = transformToApzc * transformToGecko; for (size_t i = 0; i < aOutEvent->touches.Length(); i++) { ApplyTransform(&(aOutEvent->touches[i]->mRefPoint), outTransform); } @@ -371,11 +371,11 @@ APZCTreeManager::ProcessMouseEvent(const WidgetMouseEvent& aEvent, return nsEventStatus_eIgnore; } gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; - GetInputTransforms(apzc, transformToApzc, transformToScreen); + gfx3DMatrix transformToGecko; + GetInputTransforms(apzc, transformToApzc, transformToGecko); MultiTouchInput inputForApzc(aEvent); ApplyTransform(&(inputForApzc.mTouches[0].mScreenPoint), transformToApzc); - gfx3DMatrix outTransform = transformToApzc * transformToScreen; + gfx3DMatrix outTransform = transformToApzc * transformToGecko; ApplyTransform(&aOutEvent->refPoint, outTransform); return apzc->ReceiveInputEvent(inputForApzc); } @@ -390,10 +390,10 @@ APZCTreeManager::ProcessEvent(const WidgetInputEvent& aEvent, return nsEventStatus_eIgnore; } gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; - GetInputTransforms(apzc, transformToApzc, transformToScreen); + gfx3DMatrix transformToGecko; + GetInputTransforms(apzc, transformToApzc, transformToGecko); ApplyTransform(&(aOutEvent->refPoint), transformToApzc); - gfx3DMatrix outTransform = transformToApzc * transformToScreen; + gfx3DMatrix outTransform = transformToApzc * transformToGecko; ApplyTransform(&(aOutEvent->refPoint), outTransform); return nsEventStatus_eIgnore; } @@ -542,15 +542,15 @@ APZCTreeManager::HandleOverscroll(AsyncPanZoomController* aChild, ScreenPoint aS return; gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; // ignored + gfx3DMatrix transformToGecko; // ignored // Convert start and end points to untransformed screen coordinates. - GetInputTransforms(aChild, transformToApzc, transformToScreen); + GetInputTransforms(aChild, transformToApzc, transformToGecko); ApplyTransform(&aStartPoint, transformToApzc.Inverse()); ApplyTransform(&aEndPoint, transformToApzc.Inverse()); // Convert start and end points to parent's transformed screen coordinates. - GetInputTransforms(parent, transformToApzc, transformToScreen); + GetInputTransforms(parent, transformToApzc, transformToGecko); ApplyTransform(&aStartPoint, transformToApzc); ApplyTransform(&aEndPoint, transformToApzc); @@ -670,7 +670,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a return nullptr; } -/* This function sets the aTransformToApzcOut and aTransformToScreenOut out-parameters +/* This function sets the aTransformToApzcOut and aTransformToGeckoOut out-parameters to some useful transformations that input events may need applied. This is best illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L is the layer that corresponds to the returned APZC instance, and layer R is the root @@ -718,7 +718,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a MC ... RC - Since aTransformToApzcOut is already one of the out-parameters, we set aTransformToScreenOut + Since aTransformToApzcOut is already one of the out-parameters, we set aTransformToGeckoOut to the remaining transforms (LA.Inverse() * MC * ... * RC), so that the caller code can combine it with aTransformToApzcOut to get the final transform required in this case. @@ -733,7 +733,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a */ void APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut, - gfx3DMatrix& aTransformToScreenOut) + gfx3DMatrix& aTransformToGeckoOut) { // The comments below assume there is a chain of layers L..R with L and P having APZC instances as // explained in the comment above. This function is called with aApzc at L, and the loop @@ -748,8 +748,8 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& // aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() aTransformToApzcOut = ancestorUntransform; - // aTransformToScreenOut is initialized to LA.Inverse() * MC * NC * OC - aTransformToScreenOut = asyncUntransform * aApzc->GetAncestorTransform(); + // aTransformToGeckoOut is initialized to LA.Inverse() * MC * NC * OC + aTransformToGeckoOut = asyncUntransform * aApzc->GetAncestorTransform(); for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) { // ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P @@ -761,10 +761,10 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& // aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut; - // aTransformToScreenOut is LA.Inverse() * MC * NC * OC * PC * QC * RC - aTransformToScreenOut = aTransformToScreenOut * parent->GetCSSTransform() * parent->GetAncestorTransform(); + // aTransformToGeckoOut is LA.Inverse() * MC * NC * OC * PC * QC * RC + aTransformToGeckoOut = aTransformToGeckoOut * parent->GetCSSTransform() * parent->GetAncestorTransform(); - // The above values for aTransformToApzcOut and aTransformToScreenOut when parent == P match + // The above values for aTransformToApzcOut and aTransformToGeckoOut when parent == P match // the required output as explained in the comment above GetTargetAPZC. Note that any missing terms // are async transforms that are guaranteed to be identity transforms. } diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index a7a2e185da2..c858258850e 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -277,7 +277,7 @@ public: already_AddRefed GetTargetAPZC(const ScrollableLayerGuid& aGuid); already_AddRefed GetTargetAPZC(const ScreenPoint& aPoint); void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut, - gfx3DMatrix& aTransformToScreenOut); + gfx3DMatrix& aTransformToGeckoOut); private: /* Helpers */ AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid); diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 6283afa6638..7e7968bb3cb 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -508,11 +508,11 @@ NudgeToIntegers(const gfxPoint& aPoint) static already_AddRefed GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint, - gfx3DMatrix& aTransformToApzcOut, gfx3DMatrix& aTransformToScreenOut) + gfx3DMatrix& aTransformToApzcOut, gfx3DMatrix& aTransformToGeckoOut) { nsRefPtr hit = manager->GetTargetAPZC(aPoint); if (hit) { - manager->GetInputTransforms(hit.get(), aTransformToApzcOut, aTransformToScreenOut); + manager->GetInputTransforms(hit.get(), aTransformToApzcOut, aTransformToGeckoOut); } return hit.forget(); } @@ -530,61 +530,61 @@ TEST(APZCTreeManager, HitTesting1) { nsRefPtr manager = new TestAPZCTreeManager(); gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; + gfx3DMatrix transformToGecko; // No APZC attached so hit testing will return no APZC at (20,20) - nsRefPtr hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToScreen); + nsRefPtr hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToGecko); AsyncPanZoomController* nullAPZC = nullptr; EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToScreen); + EXPECT_EQ(gfx3DMatrix(), transformToGecko); // Now we have a root APZC that will match the page SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15))); - EXPECT_EQ(gfxPoint(15, 15), transformToScreen.Transform(gfxPoint(15, 15))); + EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15))); // Now we have a sub APZC with a better fit SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController()); - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15))); - EXPECT_EQ(gfxPoint(15, 15), transformToScreen.Transform(gfxPoint(15, 15))); + EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15))); // Now test hit testing when we have two scrollable layers - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1); manager->UpdatePanZoomControllerTree(nullptr, root, false, 0); - hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko); EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(15, 15) EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15))); - EXPECT_EQ(gfxPoint(15, 15), transformToScreen.Transform(gfxPoint(15, 15))); + EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15))); // Hit test ouside the reach of layer[3,4] but inside root - hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko); EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get()); // expect hit point at LayerIntPoint(90, 90) EXPECT_EQ(gfxPoint(90, 90), transformToApzc.Transform(gfxPoint(90, 90))); - EXPECT_EQ(gfxPoint(90, 90), transformToScreen.Transform(gfxPoint(90, 90))); + EXPECT_EQ(gfxPoint(90, 90), transformToGecko.Transform(gfxPoint(90, 90))); // Hit test ouside the reach of any layer - hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToGecko); EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToScreen); - hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToScreen); + EXPECT_EQ(gfx3DMatrix(), transformToGecko); + hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToGecko); EXPECT_EQ(nullAPZC, hit.get()); EXPECT_EQ(gfx3DMatrix(), transformToApzc); - EXPECT_EQ(gfx3DMatrix(), transformToScreen); + EXPECT_EQ(gfx3DMatrix(), transformToGecko); manager->ClearTree(); } @@ -603,7 +603,7 @@ TEST(APZCTreeManager, HitTesting2) { nsRefPtr manager = new TestAPZCTreeManager(); nsRefPtr hit; gfx3DMatrix transformToApzc; - gfx3DMatrix transformToScreen; + gfx3DMatrix transformToGecko; // Set a CSS transform on one of the layers. gfx3DMatrix transform; @@ -628,10 +628,10 @@ TEST(APZCTreeManager, HitTesting2) { AsyncPanZoomController* apzc3 = layers[3]->AsContainerLayer()->GetAsyncPanZoomController(); // Hit an area that's clearly on the root layer but not any of the child layers. - hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25))); - EXPECT_EQ(gfxPoint(75, 25), transformToScreen.Transform(gfxPoint(75, 25))); + EXPECT_EQ(gfxPoint(75, 25), transformToGecko.Transform(gfxPoint(75, 25))); // Hit an area on the root that would be on layers[3] if layers[2] // weren't transformed. @@ -640,33 +640,33 @@ TEST(APZCTreeManager, HitTesting2) { // scale-only transform that we set on layers[2] would be invalid because // it would place the layer into overscroll, as its composition bounds // start at x=10 but its content at x=20). - hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75))); - EXPECT_EQ(gfxPoint(15, 75), transformToScreen.Transform(gfxPoint(15, 75))); + EXPECT_EQ(gfxPoint(15, 75), transformToGecko.Transform(gfxPoint(15, 75))); // Hit an area on layers[1]. - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzc1, hit.get()); EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25))); - EXPECT_EQ(gfxPoint(25, 25), transformToScreen.Transform(gfxPoint(25, 25))); + EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25))); // Hit an area on layers[3]. - hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75))); - // and transformToScreen should reapply it - EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75))); + // and transformToGecko should reapply it + EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(12.5, 75))); // Hit an area on layers[3] that would be on the root if layers[2] // weren't transformed. - hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc should unapply layers[2]'s transform EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75))); - // and transformToScreen should reapply it - EXPECT_EQ(gfxPoint(75, 75), transformToScreen.Transform(gfxPoint(37.5, 75))); + // and transformToGecko should reapply it + EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(37.5, 75))); // Pan the root layer upward by 50 pixels. // This causes layers[1] to scroll out of view, and an async transform @@ -679,22 +679,22 @@ TEST(APZCTreeManager, HitTesting2) { ApzcPan(apzcroot, time, 100, 50); // Hit where layers[3] used to be. It should now hit the root. - hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko); EXPECT_EQ(apzcroot, hit.get()); // transformToApzc doesn't unapply the root's own async transform EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75))); - // but transformToScreen does - EXPECT_EQ(gfxPoint(75, 125), transformToScreen.Transform(gfxPoint(75, 75))); + // but transformToGecko does + EXPECT_EQ(gfxPoint(75, 125), transformToGecko.Transform(gfxPoint(75, 75))); // Hit where layers[1] used to be and where layers[3] should now be. - hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen); + hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko); EXPECT_EQ(apzc3, hit.get()); // transformToApzc unapplies both layers[2]'s css transform and the root's // async trasnform EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25))); - // transformToScreen reapplies the css transform only (since Gecko doesn't + // transformToGecko reapplies the css transform only (since Gecko doesn't // know about async transforms) - EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75))); + EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(12.5, 75))); manager->ClearTree(); -} \ No newline at end of file +} From 13f42c1f8fbef448810f4ca34a9cefa86ca6fbcb Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Mon, 4 Nov 2013 12:05:24 -0800 Subject: [PATCH 03/13] Bumping gaia.json for 2 gaia-central revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/292078cac8cf Author: Ryan VanderMeulen Desc: Merge pull request #13334 from masap/20131104 Bug 934312 - [Homescreen] Remove CSS errors ======== https://hg.mozilla.org/integration/gaia-central/rev/92d7383d3003 Author: masap Desc: Bug 934312 - [Homescreen] Remove CSS errors --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 9c02723ff85..ec11f27c790 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "00ceae21c52602059b7614b661bc39a3c73c84de", + "revision": "292078cac8cfe841cf1cdcbac40590c1ef9c5141", "repo_path": "/integration/gaia-central" } From 33085e71f106179a4840b9e5c6805ce649b4ccb6 Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Mon, 4 Nov 2013 12:25:24 -0800 Subject: [PATCH 04/13] Bumping gaia.json for 2 gaia-central revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/265cfcff3e99 Author: James Lal Desc: Merge pull request #13360 from bobsilverberg/xfail_clock_tbpl Bug 932491 - Intermittent test_clock_set_alarm_snooze.py ======== https://hg.mozilla.org/integration/gaia-central/rev/449a4ad15a96 Author: Bob Silverberg Desc: Bug 932491 - Intermittent test_clock_set_alarm_snooze.py --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index ec11f27c790..bd95c0666ce 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "292078cac8cfe841cf1cdcbac40590c1ef9c5141", + "revision": "265cfcff3e9940e44c6baa112f451c9819f54519", "repo_path": "/integration/gaia-central" } From fd2e7a2ee06d57aad14a5345b6d6c038849f8d4f Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Mon, 4 Nov 2013 12:50:24 -0800 Subject: [PATCH 05/13] Bumping gaia.json for 2 gaia-central revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/fbe8db49928d Author: Reuben Morais Desc: Merge pull request #13046 from reubenmorais/contacts-picker Bug 929492 - Stop manually copying properties of Contact objects. r=bkelly ======== https://hg.mozilla.org/integration/gaia-central/rev/b9ea1a2713df Author: Reuben Morais Desc: Bug 929492 - Stop manually copying properties of Contact objects. r=bkelly --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index bd95c0666ce..d353021722c 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "265cfcff3e9940e44c6baa112f451c9819f54519", + "revision": "fbe8db49928d667dda2af9ed1d6c5ecdfcce49b8", "repo_path": "/integration/gaia-central" } From d011a4f6220a46105e8abff065f57172cbe9ceec Mon Sep 17 00:00:00 2001 From: Rail Aliiev Date: Mon, 4 Nov 2013 16:05:34 -0500 Subject: [PATCH 06/13] Bug 917642 - [Helix] Please update the helix blobs. r=nhirata --- b2g/config/helix/releng-helix.tt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/helix/releng-helix.tt b/b2g/config/helix/releng-helix.tt index f5e92ae73b5..ceb56142d77 100644 --- a/b2g/config/helix/releng-helix.tt +++ b/b2g/config/helix/releng-helix.tt @@ -1,7 +1,7 @@ [ { -"size": 86149048, -"digest": "4ff723d8a372e2af95e62efb8739517943f362b515b4cee78006137a8dbc97f3b42edbd2e17429eaa7fa16b7f24594ed058b7032bcb7aa2ecfe9788a212dda4d", +"size": 60589756, +"digest": "29f6a7f09edbcc777ab155de64b4c7ff8c79ea25021bacc95a44d2ee8b7b13caa72991294b05dac1d841128a90eced3f52bcc3399ead4452f6170742e0e52fc1", "algorithm": "sha512", "filename": "helix-ics.tar.xz" }, From 6e50ab1e928c96be31b2c0b0ed29e9817787759c Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Mon, 4 Nov 2013 13:15:24 -0800 Subject: [PATCH 07/13] Bumping gaia.json for 2 gaia-central revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/cf31c17dffa0 Author: James Lal Desc: Merge pull request #13361 from bobsilverberg/xfail_clock_tbpl Bug 932491 - Intermittent test_clock_set_alarm_snooze.py ======== https://hg.mozilla.org/integration/gaia-central/rev/7b4835712f51 Author: Bob Silverberg Desc: Bug 932491 - Intermittent test_clock_set_alarm_snooze.py --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index d353021722c..589192123da 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "fbe8db49928d667dda2af9ed1d6c5ecdfcce49b8", + "revision": "cf31c17dffa07c11b9c8076488a0d7b6aa28a672", "repo_path": "/integration/gaia-central" } From 346184fd6abdb694ab7cad08b1d26bc6ed1cbf21 Mon Sep 17 00:00:00 2001 From: Rail Aliiev Date: Mon, 4 Nov 2013 16:34:47 -0500 Subject: [PATCH 08/13] Backout 2ea2669b53c3, Bug 917642 - [Helix] Please update the helix blobs --- b2g/config/helix/releng-helix.tt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/b2g/config/helix/releng-helix.tt b/b2g/config/helix/releng-helix.tt index ceb56142d77..f5e92ae73b5 100644 --- a/b2g/config/helix/releng-helix.tt +++ b/b2g/config/helix/releng-helix.tt @@ -1,7 +1,7 @@ [ { -"size": 60589756, -"digest": "29f6a7f09edbcc777ab155de64b4c7ff8c79ea25021bacc95a44d2ee8b7b13caa72991294b05dac1d841128a90eced3f52bcc3399ead4452f6170742e0e52fc1", +"size": 86149048, +"digest": "4ff723d8a372e2af95e62efb8739517943f362b515b4cee78006137a8dbc97f3b42edbd2e17429eaa7fa16b7f24594ed058b7032bcb7aa2ecfe9788a212dda4d", "algorithm": "sha512", "filename": "helix-ics.tar.xz" }, From 01e6d5b1721bc055ce06f540d876c4171abbe1bf Mon Sep 17 00:00:00 2001 From: Gaia Pushbot Date: Mon, 4 Nov 2013 14:15:25 -0800 Subject: [PATCH 09/13] Bumping gaia.json for 2 gaia-central revision(s) a=gaia-bump ======== https://hg.mozilla.org/integration/gaia-central/rev/e9d3946c6e4c Author: Eitan Isaacson Desc: Merge pull request #13362 from eeejay/bug-934653 Bug 934653 - [system] aria-hidden on windows element is inverted. r=alive ======== https://hg.mozilla.org/integration/gaia-central/rev/be1da7f3fd8e Author: Eitan Isaacson Desc: Bug 934653 - [system] aria-hidden on windows element is inverted. --- b2g/config/gaia.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 589192123da..249b4c1de60 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "cf31c17dffa07c11b9c8076488a0d7b6aa28a672", + "revision": "e9d3946c6e4c26c60f67b8efac40e14785b634d3", "repo_path": "/integration/gaia-central" } From dbbaa3d8ba1ff64e97aa71031d736abb0d660b92 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Mon, 4 Nov 2013 17:27:39 -0500 Subject: [PATCH 10/13] Bug 862899 - AudioChannelAgent in the FMRadio API. r=mchen, r=khuey --- dom/fmradio/FMRadio.cpp | 71 +++++++++++++++++++++++++++++++ dom/fmradio/FMRadio.h | 12 ++++++ dom/fmradio/FMRadioService.cpp | 30 ++++++++----- dom/fmradio/FMRadioService.h | 5 +++ dom/fmradio/ipc/FMRadioChild.cpp | 6 +++ dom/fmradio/ipc/FMRadioChild.h | 2 + dom/fmradio/ipc/FMRadioParent.cpp | 7 +++ dom/fmradio/ipc/FMRadioParent.h | 3 ++ dom/fmradio/ipc/PFMRadio.ipdl | 5 +++ 9 files changed, 131 insertions(+), 10 deletions(-) diff --git a/dom/fmradio/FMRadio.cpp b/dom/fmradio/FMRadio.cpp index 3aeff819a45..4df52faff1c 100644 --- a/dom/fmradio/FMRadio.cpp +++ b/dom/fmradio/FMRadio.cpp @@ -14,6 +14,10 @@ #include "mozilla/dom/PFMRadioChild.h" #include "mozilla/dom/FMRadioService.h" #include "DOMRequest.h" +#include "nsDOMClassInfo.h" +#include "nsIDocShell.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIAudioManager.h" #undef LOG #define LOG(args...) FM_LOG("FMRadio", args) @@ -110,6 +114,27 @@ FMRadio::Init(nsPIDOMWindow *aWindow) mHeadphoneState = GetCurrentSwitchState(SWITCH_HEADPHONES); RegisterSwitchObserver(SWITCH_HEADPHONES, this); } + + nsCOMPtr target = do_QueryInterface(GetOwner()); + NS_ENSURE_TRUE_VOID(target); + target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this, + /* useCapture = */ true, + /* wantsUntrusted = */ false); + + mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1"); + if (!mAudioChannelAgent) { + return; + } + + mAudioChannelAgent->InitWithWeakCallback(nsIAudioChannelAgent::AUDIO_AGENT_CHANNEL_CONTENT, + this); + + nsCOMPtr docshell = do_GetInterface(GetOwner()); + if (docshell) { + bool isActive = false; + docshell->GetIsActive(&isActive); + mAudioChannelAgent->SetVisibilityState(isActive); + } } void @@ -121,6 +146,11 @@ FMRadio::Shutdown() UnregisterSwitchObserver(SWITCH_HEADPHONES, this); } + nsCOMPtr target = do_QueryInterface(GetOwner()); + NS_ENSURE_TRUE_VOID(target); + target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this, + /* useCapture = */ true); + mIsShutdown = true; } @@ -151,8 +181,14 @@ FMRadio::Notify(const FMRadioEventType& aType) break; case EnabledChanged: if (Enabled()) { + int32_t playingState = 0; + mAudioChannelAgent->StartPlaying(&playingState); + SetCanPlay(playingState == AudioChannelState::AUDIO_CHANNEL_STATE_NORMAL); + DispatchTrustedEvent(NS_LITERAL_STRING("enabled")); } else { + mAudioChannelAgent->StopPlaying(); + DispatchTrustedEvent(NS_LITERAL_STRING("disabled")); } break; @@ -284,8 +320,43 @@ FMRadio::CancelSeek() return r.forget(); } +NS_IMETHODIMP +FMRadio::HandleEvent(nsIDOMEvent* aEvent) +{ + nsAutoString type; + aEvent->GetType(type); + + if (!type.EqualsLiteral("visibilitychange")) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr docshell = do_GetInterface(GetOwner()); + NS_ENSURE_TRUE(docshell, NS_ERROR_FAILURE); + + bool isActive = false; + docshell->GetIsActive(&isActive); + + mAudioChannelAgent->SetVisibilityState(isActive); + return NS_OK; +} + +NS_IMETHODIMP +FMRadio::CanPlayChanged(int32_t aCanPlay) +{ + SetCanPlay(aCanPlay == AudioChannelState::AUDIO_CHANNEL_STATE_NORMAL); + return NS_OK; +} + +void +FMRadio::SetCanPlay(bool aCanPlay) +{ + IFMRadioService::Singleton()->EnableAudio(aCanPlay); +} + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FMRadio) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(FMRadio, nsDOMEventTargetHelper) diff --git a/dom/fmradio/FMRadio.h b/dom/fmradio/FMRadio.h index a4cf8293034..9ec1d082cf2 100644 --- a/dom/fmradio/FMRadio.h +++ b/dom/fmradio/FMRadio.h @@ -11,6 +11,7 @@ #include "nsCycleCollectionParticipant.h" #include "mozilla/HalTypes.h" #include "nsWeakReference.h" +#include "AudioChannelAgent.h" class nsPIDOMWindow; class nsIScriptContext; @@ -23,6 +24,9 @@ class FMRadio MOZ_FINAL : public nsDOMEventTargetHelper , public hal::SwitchObserver , public FMRadioEventObserver , public nsSupportsWeakReference + , public nsIAudioChannelAgentCallback + , public nsIDOMEventListener + { friend class FMRadioRequest; @@ -30,6 +34,7 @@ public: FMRadio(); NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper) @@ -78,12 +83,19 @@ public: IMPL_EVENT_HANDLER(antennaavailablechange); IMPL_EVENT_HANDLER(frequencychange); + // nsIDOMEventListener + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); + private: ~FMRadio(); + void SetCanPlay(bool aCanPlay); + hal::SwitchState mHeadphoneState; bool mHasInternalAntenna; bool mIsShutdown; + + nsCOMPtr mAudioChannelAgent; }; END_FMRADIO_NAMESPACE diff --git a/dom/fmradio/FMRadioService.cpp b/dom/fmradio/FMRadioService.cpp index a05f87cf7c7..e06e036a72a 100644 --- a/dom/fmradio/FMRadioService.cpp +++ b/dom/fmradio/FMRadioService.cpp @@ -123,12 +123,8 @@ public: info.spaceType() = mSpaceType; EnableFMRadio(info); + IFMRadioService::Singleton()->EnableAudio(true); - nsCOMPtr audioManager = - do_GetService(NS_AUDIOMANAGER_CONTRACTID); - audioManager->SetFmRadioAudioEnabled(true); - - // TODO apply path from bug 862899: AudioChannelAgent per process return NS_OK; } @@ -209,11 +205,7 @@ public: // Fix Bug 796733. DisableFMRadio should be called before // SetFmRadioAudioEnabled to prevent the annoying beep sound. DisableFMRadio(); - - nsCOMPtr audioManager = - do_GetService(NS_AUDIOMANAGER_CONTRACTID); - - audioManager->SetFmRadioAudioEnabled(false); + IFMRadioService::Singleton()->EnableAudio(false); return NS_OK; } @@ -299,6 +291,24 @@ FMRadioService::RemoveObserver(FMRadioEventObserver* aObserver) } } +void +FMRadioService::EnableAudio(bool aAudioEnabled) +{ + MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); + + nsCOMPtr audioManager = + do_GetService("@mozilla.org/telephony/audiomanager;1"); + if (!audioManager) { + return; + } + + bool AudioEnabled; + audioManager->GetFmRadioAudioEnabled(&AudioEnabled); + if (AudioEnabled != aAudioEnabled) { + audioManager->SetFmRadioAudioEnabled(aAudioEnabled); + } +} + /** * Round the frequency to match the range of frequency and the channel width. If * the given frequency is out of range, return 0. For example: diff --git a/dom/fmradio/FMRadioService.h b/dom/fmradio/FMRadioService.h index ce44bcd2379..5dfcbee3170 100644 --- a/dom/fmradio/FMRadioService.h +++ b/dom/fmradio/FMRadioService.h @@ -117,6 +117,9 @@ public: virtual void AddObserver(FMRadioEventObserver* aObserver) = 0; virtual void RemoveObserver(FMRadioEventObserver* aObserver) = 0; + // Enable/Disable FMRadio + virtual void EnableAudio(bool aAudioEnabled) = 0; + /** * Static method to return the singleton instance. If it's in the child * process, we will get an object of FMRadioChild. @@ -164,6 +167,8 @@ public: virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; + virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE; + /* FMRadioObserver */ void Notify(const hal::FMRadioOperationInformation& aInfo) MOZ_OVERRIDE; diff --git a/dom/fmradio/ipc/FMRadioChild.cpp b/dom/fmradio/ipc/FMRadioChild.cpp index f1f871410a8..0433bfce199 100644 --- a/dom/fmradio/ipc/FMRadioChild.cpp +++ b/dom/fmradio/ipc/FMRadioChild.cpp @@ -165,6 +165,12 @@ FMRadioChild::DeallocPFMRadioRequestChild(PFMRadioRequestChild* aActor) return true; } +void +FMRadioChild::EnableAudio(bool aAudioEnabled) +{ + SendEnableAudio(aAudioEnabled); +} + // static FMRadioChild* FMRadioChild::Singleton() diff --git a/dom/fmradio/ipc/FMRadioChild.h b/dom/fmradio/ipc/FMRadioChild.h index f964df32264..ff9f6162f04 100644 --- a/dom/fmradio/ipc/FMRadioChild.h +++ b/dom/fmradio/ipc/FMRadioChild.h @@ -51,6 +51,8 @@ public: virtual void AddObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; virtual void RemoveObserver(FMRadioEventObserver* aObserver) MOZ_OVERRIDE; + virtual void EnableAudio(bool aAudioEnabled) MOZ_OVERRIDE; + /* PFMRadioChild */ virtual bool Recv__delete__() MOZ_OVERRIDE; diff --git a/dom/fmradio/ipc/FMRadioParent.cpp b/dom/fmradio/ipc/FMRadioParent.cpp index cf2ad36565d..60bed9dcf6c 100644 --- a/dom/fmradio/ipc/FMRadioParent.cpp +++ b/dom/fmradio/ipc/FMRadioParent.cpp @@ -97,5 +97,12 @@ FMRadioParent::Notify(const FMRadioEventType& aType) } } +bool +FMRadioParent::RecvEnableAudio(const bool& aAudioEnabled) +{ + IFMRadioService::Singleton()->EnableAudio(aAudioEnabled); + return true; +} + END_FMRADIO_NAMESPACE diff --git a/dom/fmradio/ipc/FMRadioParent.h b/dom/fmradio/ipc/FMRadioParent.h index 73aba59cb90..18f9bd659b3 100644 --- a/dom/fmradio/ipc/FMRadioParent.h +++ b/dom/fmradio/ipc/FMRadioParent.h @@ -33,6 +33,9 @@ public: /* FMRadioEventObserver */ virtual void Notify(const FMRadioEventType& aType) MOZ_OVERRIDE; + + virtual bool + RecvEnableAudio(const bool& aAudioEnabled) MOZ_OVERRIDE; }; END_FMRADIO_NAMESPACE diff --git a/dom/fmradio/ipc/PFMRadio.ipdl b/dom/fmradio/ipc/PFMRadio.ipdl index d7049268df6..be863e1a5e1 100644 --- a/dom/fmradio/ipc/PFMRadio.ipdl +++ b/dom/fmradio/ipc/PFMRadio.ipdl @@ -86,6 +86,11 @@ parent: * is more error prone. */ PFMRadioRequest(FMRadioRequestArgs requestType); + + /** + * Enable/Disable audio + */ + EnableAudio(bool audioEnabled); }; } // namespace dom From cf22d443e60b2a6ce71d3b3fc683d2284241102e Mon Sep 17 00:00:00 2001 From: CJKu Date: Mon, 4 Nov 2013 17:27:39 -0500 Subject: [PATCH 11/13] Bug 924724 - Shutdown hang in Media Encoder when running state machine mochitest in bug 920595. r=roc --- content/media/MediaRecorder.cpp | 91 ++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/content/media/MediaRecorder.cpp b/content/media/MediaRecorder.cpp index 878c615afcf..7d891f864da 100644 --- a/content/media/MediaRecorder.cpp +++ b/content/media/MediaRecorder.cpp @@ -61,8 +61,10 @@ NS_IMPL_RELEASE_INHERITED(MediaRecorder, nsDOMEventTargetHelper) * 2) A Session is destroyed in DestroyRunnable after MediaRecorder::Stop being called * _and_ all encoded media data been passed to OnDataAvailable handler. */ -class MediaRecorder::Session +class MediaRecorder::Session: public nsIObserver { + NS_DECL_THREADSAFE_ISUPPORTS + // Main thread task. // Create a blob event and send back to client. class PushBlobRunnable : public nsRunnable @@ -114,7 +116,7 @@ class MediaRecorder::Session class DestroyRunnable : public nsRunnable { public: - DestroyRunnable(Session *aSession) + DestroyRunnable(const already_AddRefed &aSession) : mSession(aSession) {} NS_IMETHODIMP Run() @@ -122,12 +124,16 @@ class MediaRecorder::Session MOZ_ASSERT(NS_IsMainThread() && mSession.get()); MediaRecorder *recorder = mSession->mRecorder; - // If MediaRecoder is not in Inactive mode, call MediaRecoder::Stop - // and dispatch DestroyRunnable again. + // SourceMediaStream is ended, and send out TRACK_EVENT_END notification. + // Read Thread will be terminate soon. + // We need to switch MediaRecorder to "Stop" state first to make sure + // MediaRecorder is not associated with this Session anymore, then, it's + // safe to delete this Session. if (recorder->mState != RecordingState::Inactive) { ErrorResult result; recorder->Stop(result); NS_DispatchToMainThread(new DestroyRunnable(mSession.forget())); + return NS_OK; } @@ -135,14 +141,12 @@ class MediaRecorder::Session recorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop")); recorder->SetMimeType(NS_LITERAL_STRING("")); - // Delete session object. - mSession = nullptr; - return NS_OK; } private: - nsAutoPtr mSession; + // Call mSession::Release automatically while DestroyRunnable be destroy. + nsRefPtr mSession; }; friend class PushBlobRunnable; @@ -156,21 +160,16 @@ public: { MOZ_ASSERT(NS_IsMainThread()); + AddRef(); mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER); } // Only DestroyRunnable is allowed to delete Session object. - ~Session() + virtual ~Session() { MOZ_ASSERT(NS_IsMainThread()); - if (mInputPort.get()) { - mInputPort->Destroy(); - } - - if (mTrackUnionStream.get()) { - mTrackUnionStream->Destroy(); - } + CleanupStreams(); } void Start() @@ -183,17 +182,16 @@ public: if (!mReadThread) { nsresult rv = NS_NewNamedThread("Media Encoder", getter_AddRefs(mReadThread)); if (NS_FAILED(rv)) { - if (mInputPort.get()) { - mInputPort->Destroy(); - } - if (mTrackUnionStream.get()) { - mTrackUnionStream->Destroy(); - } + CleanupStreams(); mRecorder->NotifyError(rv); return; } } + // In case source media stream does not notify track end, recieve + // shutdown notification and stop Read Thread. + nsContentUtils::RegisterShutdownObserver(this); + mReadThread->Dispatch(new ExtractRunnable(this), NS_DISPATCH_NORMAL); } @@ -201,18 +199,8 @@ public: { MOZ_ASSERT(NS_IsMainThread()); - // Shutdown mEncoder to stop Session::Extract - if (mInputPort.get()) - { - mInputPort->Destroy(); - mInputPort = nullptr; - } - - if (mTrackUnionStream.get()) - { - mTrackUnionStream->Destroy(); - mTrackUnionStream = nullptr; - } + CleanupStreams(); + nsContentUtils::UnregisterShutdownObserver(this); } void Pause() @@ -233,6 +221,7 @@ public: { nsString mimeType; mRecorder->GetMimeType(mimeType); + return mEncodedBufferCache->ExtractBlob(mimeType); } @@ -273,7 +262,7 @@ private: NS_DispatchToMainThread(new PushBlobRunnable(this)); // Destroy this session object in main thread. - NS_DispatchToMainThread(new DestroyRunnable(this)); + NS_DispatchToMainThread(new DestroyRunnable(already_AddRefed(this))); } // Bind media source with MediaEncoder to receive raw media data. @@ -281,15 +270,17 @@ private: { MOZ_ASSERT(NS_IsMainThread()); + // Create a Track Union Stream MediaStreamGraph* gm = mRecorder->mStream->GetStream()->Graph(); mTrackUnionStream = gm->CreateTrackUnionStream(nullptr); MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed"); mTrackUnionStream->SetAutofinish(true); + // Bind this Track Union Stream with Source Media mInputPort = mTrackUnionStream->AllocateInputPort(mRecorder->mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT); - // Allocate encoder and bind with union stream. + // Allocate encoder and bind with the Track Union Stream. mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING("")); MOZ_ASSERT(mEncoder, "CreateEncoder failed"); @@ -298,11 +289,37 @@ private: } } + void CleanupStreams() + { + if (mInputPort.get()) { + mInputPort->Destroy(); + mInputPort = nullptr; + } + + if (mTrackUnionStream.get()) { + mTrackUnionStream->Destroy(); + mTrackUnionStream = nullptr; + } + } + + NS_IMETHODIMP Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) + { + MOZ_ASSERT(NS_IsMainThread()); + + if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + // Force stop Session to terminate Read Thread. + Stop(); + } + + return NS_OK; + } + private: // Hold a reference to MediaRecoder to make sure MediaRecoder be // destroyed after all session object dead. nsRefPtr mRecorder; + // Receive track data from source and dispatch to Encoder. // Pause/ Resume controller. nsRefPtr mTrackUnionStream; nsRefPtr mInputPort; @@ -320,6 +337,8 @@ private: const int32_t mTimeSlice; }; +NS_IMPL_ISUPPORTS1(MediaRecorder::Session, nsIObserver) + MediaRecorder::~MediaRecorder() { MOZ_ASSERT(mSession == nullptr); From bdbae3a6be21f2722ffe1f3a777394fe0f0d17e6 Mon Sep 17 00:00:00 2001 From: "Antonio M. Amaya" Date: Fri, 1 Nov 2013 02:58:28 +0100 Subject: [PATCH 12/13] Bug 932843 - Allow the installation of operator packaged apps without network connection. r=fabrice --- dom/apps/src/Webapps.jsm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index a364e80c4a6..c14c247c236 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -2154,16 +2154,17 @@ this.DOMApplicationRegistry = { queuedDownload: {}, queuedPackageDownload: {}, - onInstallSuccessAck: function onInstallSuccessAck(aManifestURL) { +onInstallSuccessAck: function onInstallSuccessAck(aManifestURL, + aDontNeedNetwork) { // If we are offline, register to run when we'll be online. - if (Services.io.offline) { + if ((Services.io.offline) && !aDontNeedNetwork) { let onlineWrapper = { observe: function(aSubject, aTopic, aData) { Services.obs.removeObserver(onlineWrapper, "network:offline-status-changed"); DOMApplicationRegistry.onInstallSuccessAck(aManifestURL); } - } + }; Services.obs.addObserver(onlineWrapper, "network:offline-status-changed", false); return; @@ -2368,12 +2369,13 @@ this.DOMApplicationRegistry = { aInstallSuccessCallback(app.manifest); } } - + let dontNeedNetwork = false; if (manifest.package_path) { // If it is a local app then it must been installed from a local file // instead of web. let origPath = jsonManifest.package_path; if (aData.app.localInstallPath) { + dontNeedNetwork = true; jsonManifest.package_path = "file://" + aData.app.localInstallPath; } // origin for install apps is meaningless here, since it's app:// and this @@ -2390,7 +2392,7 @@ this.DOMApplicationRegistry = { if (aData.forceSuccessAck) { // If it's a local install, there's no content process so just // ack the install. - this.onInstallSuccessAck(app.manifestURL); + this.onInstallSuccessAck(app.manifestURL, dontNeedNetwork); } }, From 6911fa7473308cbb9b70fcb97b444bc2c4aa7bc6 Mon Sep 17 00:00:00 2001 From: Donovan Preston Date: Mon, 4 Nov 2013 17:27:40 -0500 Subject: [PATCH 13/13] Bug 922239 - Disable the slow script dialog for Open Web Apps. Apps can be killed using the normal procedure for killing apps on each OS. r=myk --- webapprt/prefs.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/webapprt/prefs.js b/webapprt/prefs.js index 7980104441d..b8b151c2908 100644 --- a/webapprt/prefs.js +++ b/webapprt/prefs.js @@ -49,6 +49,11 @@ pref("general.smoothScroll", true); // WebPayment pref("dom.mozPay.enabled", true); +// Disable slow script dialog for apps +pref("dom.max_script_run_time", 0); +pref("dom.max_chrome_script_run_time", 0); + + #ifndef RELEASE_BUILD // Enable mozPay default provider pref("dom.payment.provider.0.name", "Firefox Marketplace");