Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: ui/compositor/compositor_unittest.cc

Issue 1414533003: Make ui::Compositor BeginFrame subscription robust (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup comment Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/compositor/compositor.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/compositor/compositor_unittest.cc
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc
index a53bdc2ab0f2b5d1095bde808917bb7947ca3c72..667845a0894eefb78ac05b1d64be10d1fb11294c 100644
--- a/ui/compositor/compositor_unittest.cc
+++ b/ui/compositor/compositor_unittest.cc
@@ -19,6 +19,10 @@ using testing::_;
namespace ui {
namespace {
+ACTION_P2(RemoveObserver, compositor, observer) {
+ compositor->RemoveBeginFrameObserver(observer);
+}
+
class MockCompositorBeginFrameObserver : public CompositorBeginFrameObserver {
public:
MOCK_METHOD1(OnSendBeginFrame, void(const cc::BeginFrameArgs&));
@@ -91,27 +95,32 @@ TEST_F(CompositorTest, AddAndRemoveBeginFrameObserver) {
cc::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE,
base::TimeTicks::FromInternalValue(33));
- // Simulate to trigger new BeginFrame by using |args|.
- compositor()->SendBeginFramesToChildren(args);
+ MockCompositorBeginFrameObserver test_observer;
+ MockCompositorBeginFrameObserver test_observer2;
+
+ // Add a single observer.
+ compositor()->AddBeginFrameObserver(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer);
// When |missed_begin_frame_args_| is sent, its type is set to MISSED.
cc::BeginFrameArgs expected_args(args);
- expected_args.type = cc::BeginFrameArgs::MISSED;
+ cc::BeginFrameArgs expected_missed_args(args);
+ expected_missed_args.type = cc::BeginFrameArgs::MISSED;
- MockCompositorBeginFrameObserver test_observer;
- MockCompositorBeginFrameObserver test_observer2;
+ // Simulate to trigger new BeginFrame by using |args|.
EXPECT_CALL(test_observer, OnSendBeginFrame(expected_args));
- EXPECT_CALL(test_observer2, OnSendBeginFrame(expected_args));
+ compositor()->SendBeginFramesToChildren(args);
+ Mock::VerifyAndClearExpectations(&test_observer);
// When new observer is added, Compositor immediately calls OnSendBeginFrame
// with |missed_begin_frame_args_|.
- compositor()->AddBeginFrameObserver(&test_observer);
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(expected_missed_args));
compositor()->AddBeginFrameObserver(&test_observer2);
Mock::VerifyAndClearExpectations(&test_observer);
Mock::VerifyAndClearExpectations(&test_observer2);
// When |test_observer2| is removed and added again, it will be called again.
- EXPECT_CALL(test_observer2, OnSendBeginFrame(expected_args));
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(expected_missed_args));
compositor()->RemoveBeginFrameObserver(&test_observer2);
compositor()->AddBeginFrameObserver(&test_observer2);
Mock::VerifyAndClearExpectations(&test_observer2);
@@ -121,12 +130,69 @@ TEST_F(CompositorTest, AddAndRemoveBeginFrameObserver) {
EXPECT_CALL(test_observer2, OnSendBeginFrame(_)).Times(0);
compositor()->RemoveBeginFrameObserver(&test_observer);
compositor()->RemoveBeginFrameObserver(&test_observer2);
+ compositor()->SendBeginFramesToChildren(args);
compositor()->AddBeginFrameObserver(&test_observer2);
Mock::VerifyAndClearExpectations(&test_observer2);
compositor()->RemoveBeginFrameObserver(&test_observer2);
}
+TEST_F(CompositorTest, RemoveBeginFrameObserverWhileSendingBeginFrame) {
+ cc::BeginFrameArgs args = cc::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, base::TimeTicks::FromInternalValue(33));
+
+ cc::BeginFrameArgs expected_args(args);
+ cc::BeginFrameArgs expected_missed_args(args);
+ expected_missed_args.type = cc::BeginFrameArgs::MISSED;
+
+ // Add both observers, and simulate removal of |test_observer2| during
+ // BeginFrame dispatch (implicitly triggered when the observer is added).
+ MockCompositorBeginFrameObserver test_observer;
+ MockCompositorBeginFrameObserver test_observer2;
+ EXPECT_CALL(test_observer, OnSendBeginFrame(expected_args));
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(expected_missed_args))
+ .WillOnce(RemoveObserver(compositor(), &test_observer2));
+
+ // When a new observer is added, Compositor immediately calls OnSendBeginFrame
+ // with |missed_begin_frame_args_|.
+ compositor()->AddBeginFrameObserver(&test_observer);
+ compositor()->SendBeginFramesToChildren(args);
+ compositor()->AddBeginFrameObserver(&test_observer2);
+ Mock::VerifyAndClearExpectations(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer2);
+
+ // |test_observer2| was removed during the previous implicit BeginFrame
+ // dispatch, and should not get the new frame.
+ expected_args.type = cc::BeginFrameArgs::NORMAL;
+ EXPECT_CALL(test_observer, OnSendBeginFrame(expected_args));
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(_)).Times(0);
+ compositor()->SendBeginFramesToChildren(args);
+ Mock::VerifyAndClearExpectations(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer2);
+
+ // Now remove |test_observer| during explicit BeginFrame dispatch.
+ EXPECT_CALL(test_observer, OnSendBeginFrame(expected_args))
+ .WillOnce(RemoveObserver(compositor(), &test_observer));
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(_)).Times(0);
+ compositor()->SendBeginFramesToChildren(args);
+ Mock::VerifyAndClearExpectations(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer2);
+
+ // No observers should get the new frame.
+ EXPECT_CALL(test_observer, OnSendBeginFrame(_)).Times(0);
+ EXPECT_CALL(test_observer2, OnSendBeginFrame(_)).Times(0);
+ compositor()->SendBeginFramesToChildren(args);
+ Mock::VerifyAndClearExpectations(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer2);
+
+ // Adding a new observer should not trigger a missed frame, as the
+ // previous frame had no observers.
+ EXPECT_CALL(test_observer, OnSendBeginFrame(_)).Times(0);
+ compositor()->AddBeginFrameObserver(&test_observer);
+ compositor()->RemoveBeginFrameObserver(&test_observer);
+ Mock::VerifyAndClearExpectations(&test_observer);
+}
+
TEST_F(CompositorTest, ReleaseWidgetWithOutputSurfaceNeverCreated) {
compositor()->SetVisible(false);
EXPECT_EQ(gfx::kNullAcceleratedWidget,
« no previous file with comments | « ui/compositor/compositor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698