Index: ui/compositor/compositor_unittest.cc |
diff --git a/ui/compositor/compositor_unittest.cc b/ui/compositor/compositor_unittest.cc |
index e62e0b8c430a84131a25aeb4a6c3ee619a3eab11..f528c9ef85f5f6faa1769f3ba06b759f57f4c672 100644 |
--- a/ui/compositor/compositor_unittest.cc |
+++ b/ui/compositor/compositor_unittest.cc |
@@ -62,36 +62,134 @@ class CompositorTest : public testing::Test { |
DISALLOW_COPY_AND_ASSIGN(CompositorTest); |
}; |
+class MockCompositorLockClient |
+ : NON_EXPORTED_BASE(public ui::CompositorLockClient) { |
+ public: |
+ MOCK_METHOD0(CompositorLockTimedOut, void()); |
+}; |
+ |
} // namespace |
TEST_F(CompositorTest, LocksTimeOut) { |
- scoped_refptr<ui::CompositorLock> lock; |
+ std::unique_ptr<CompositorLock> lock; |
+ |
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(100); |
+ |
{ |
+ testing::StrictMock<MockCompositorLockClient> lock_client; |
base::RunLoop run_loop; |
- // Ensure that the lock times out by default. |
- lock = compositor()->GetCompositorLock(); |
+ // This lock has a timeout. |
+ lock = compositor()->GetCompositorLock(&lock_client, timeout); |
EXPECT_TRUE(compositor()->IsLocked()); |
- task_runner()->PostDelayedTask( |
- FROM_HERE, run_loop.QuitClosure(), |
- base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout); |
+ EXPECT_CALL(lock_client, CompositorLockTimedOut()).Times(1); |
run_loop.Run(); |
EXPECT_FALSE(compositor()->IsLocked()); |
} |
{ |
+ testing::StrictMock<MockCompositorLockClient> lock_client; |
base::RunLoop run_loop; |
- // Ensure that the lock does not time out when set. |
- compositor()->SetLocksWillTimeOut(false); |
- lock = compositor()->GetCompositorLock(); |
+ // This lock has no timeout. |
+ lock = compositor()->GetCompositorLock(&lock_client, base::TimeDelta()); |
EXPECT_TRUE(compositor()->IsLocked()); |
- task_runner()->PostDelayedTask( |
- FROM_HERE, run_loop.QuitClosure(), |
- base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout); |
+ EXPECT_CALL(lock_client, CompositorLockTimedOut()).Times(0); |
run_loop.Run(); |
EXPECT_TRUE(compositor()->IsLocked()); |
} |
} |
+TEST_F(CompositorTest, MultipleLockClients) { |
+ testing::StrictMock<MockCompositorLockClient> lock_client1; |
+ std::unique_ptr<CompositorLock> lock1; |
+ testing::StrictMock<MockCompositorLockClient> lock_client2; |
+ std::unique_ptr<CompositorLock> lock2; |
+ |
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1); |
+ base::RunLoop run_loop; |
+ // Both locks are grabbed from the Compositor with a separate client. |
+ lock1 = compositor()->GetCompositorLock(&lock_client1, timeout); |
+ lock2 = compositor()->GetCompositorLock(&lock_client2, timeout); |
+ EXPECT_TRUE(compositor()->IsLocked()); |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout); |
+ // Both clients get notified of timeout. |
+ EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(1); |
+ EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1); |
+ run_loop.Run(); |
+ EXPECT_FALSE(compositor()->IsLocked()); |
+} |
+ |
+TEST_F(CompositorTest, ExtendingLifeOfLockDoesntUseDeadClient) { |
+ testing::StrictMock<MockCompositorLockClient> lock_client1; |
+ std::unique_ptr<CompositorLock> lock1; |
+ testing::StrictMock<MockCompositorLockClient> lock_client2; |
+ std::unique_ptr<CompositorLock> lock2; |
+ |
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1); |
+ base::RunLoop run_loop; |
+ |
+ // One lock is grabbed from the compositor with a client. The other |
+ // extends its lifetime past that of the first. |
+ lock1 = compositor()->GetCompositorLock(&lock_client1, timeout); |
+ EXPECT_TRUE(compositor()->IsLocked()); |
+ |
+ // This also locks the compositor and will do so past |lock1| ending. |
+ lock2 = compositor()->GetCompositorLock(&lock_client2, timeout); |
+ // |lock1| is destroyed, so it won't timeout but |lock2| will. |
+ lock1 = nullptr; |
+ |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout); |
+ |
+ EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(0); |
+ EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1); |
+ run_loop.Run(); |
+ EXPECT_FALSE(compositor()->IsLocked()); |
+} |
+ |
+TEST_F(CompositorTest, AddingLocksDoesNotExtendTimeout) { |
+ testing::StrictMock<MockCompositorLockClient> lock_client1; |
+ std::unique_ptr<CompositorLock> lock1; |
+ testing::StrictMock<MockCompositorLockClient> lock_client2; |
+ std::unique_ptr<CompositorLock> lock2; |
+ |
+ base::TimeDelta timeout1 = base::TimeDelta::FromMilliseconds(1); |
+ base::TimeDelta timeout2 = base::TimeDelta::FromMilliseconds(10); |
+ base::RunLoop run_loop; |
+ |
+ // The first lock has a short timeout. |
+ lock1 = compositor()->GetCompositorLock(&lock_client1, timeout1); |
+ EXPECT_TRUE(compositor()->IsLocked()); |
+ |
+ // The second lock has a longer timeout, but since a lock is active, |
+ // the first one is used for both. |
+ lock2 = compositor()->GetCompositorLock(&lock_client2, timeout2); |
+ |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout1); |
+ |
+ EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(1); |
+ EXPECT_CALL(lock_client2, CompositorLockTimedOut()).Times(1); |
+ run_loop.Run(); |
+ EXPECT_FALSE(compositor()->IsLocked()); |
+} |
+ |
+TEST_F(CompositorTest, LockIsDestroyedDoesntTimeout) { |
+ base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(1); |
+ base::RunLoop run_loop; |
+ |
+ testing::StrictMock<MockCompositorLockClient> lock_client1; |
+ std::unique_ptr<CompositorLock> lock1; |
+ lock1 = compositor()->GetCompositorLock(&lock_client1, timeout); |
+ EXPECT_TRUE(compositor()->IsLocked()); |
+ task_runner()->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), timeout); |
+ // The CompositorLockClient is destroyed when |lock1| is released. |
+ lock1 = nullptr; |
+ // The client isn't called as a result. |
+ EXPECT_CALL(lock_client1, CompositorLockTimedOut()).Times(0); |
+ run_loop.Run(); |
+ EXPECT_FALSE(compositor()->IsLocked()); |
+} |
+ |
TEST_F(CompositorTest, ReleaseWidgetWithOutputSurfaceNeverCreated) { |
compositor()->SetVisible(false); |
EXPECT_EQ(gfx::kNullAcceleratedWidget, |