1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "screen_orientation_dispatcher.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "content/common/screen_orientation_messages.h"
12 #include "content/public/test/test_utils.h"
13 #include "ipc/ipc_test_sink.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebLockOrientationCallback.h"
19 // MockLockOrientationCallback is an implementation of
20 // WebLockOrientationCallback and takes a LockOrientationResultHolder* as a
21 // parameter when being constructed. The |results_| pointer is owned by the
22 // caller and not by the callback object. The intent being that as soon as the
23 // callback is resolved, it will be killed so we use the
24 // LockOrientationResultHolder to know in which state the callback object is at
26 class MockLockOrientationCallback
:
27 public blink::WebLockOrientationCallback
{
29 struct LockOrientationResultHolder
{
30 LockOrientationResultHolder()
31 : succeeded_(false), failed_(false) {}
35 blink::WebLockOrientationError error_
;
38 explicit MockLockOrientationCallback(LockOrientationResultHolder
* results
)
39 : results_(results
) {}
41 virtual void onSuccess() {
42 results_
->succeeded_
= true;
45 virtual void onError(blink::WebLockOrientationError error
) {
46 results_
->failed_
= true;
47 results_
->error_
= error
;
51 virtual ~MockLockOrientationCallback() {}
53 LockOrientationResultHolder
* results_
;
56 class ScreenOrientationDispatcherWithSink
: public ScreenOrientationDispatcher
{
58 explicit ScreenOrientationDispatcherWithSink(IPC::TestSink
* sink
)
59 :ScreenOrientationDispatcher(NULL
) , sink_(sink
) {
62 virtual bool Send(IPC::Message
* message
) override
{
63 return sink_
->Send(message
);
69 class ScreenOrientationDispatcherTest
: public testing::Test
{
71 virtual void SetUp() override
{
72 dispatcher_
.reset(new ScreenOrientationDispatcherWithSink(&sink_
));
75 int GetFirstLockRequestIdFromSink() {
76 const IPC::Message
* msg
= sink().GetFirstMessageMatching(
77 ScreenOrientationHostMsg_LockRequest::ID
);
78 EXPECT_TRUE(msg
!= NULL
);
80 Tuple2
<blink::WebScreenOrientationLockType
,int> params
;
81 ScreenOrientationHostMsg_LockRequest::Read(msg
, ¶ms
);
85 IPC::TestSink
& sink() {
89 void LockOrientation(blink::WebScreenOrientationLockType orientation
,
90 blink::WebLockOrientationCallback
* callback
) {
91 dispatcher_
->lockOrientation(orientation
, callback
);
94 void UnlockOrientation() {
95 dispatcher_
->unlockOrientation();
98 void OnMessageReceived(const IPC::Message
& message
) {
99 dispatcher_
->OnMessageReceived(message
);
102 int routing_id() const {
103 // We return a fake routing_id() in the context of this test.
108 scoped_ptr
<ScreenOrientationDispatcher
> dispatcher_
;
111 // Test that calling lockOrientation() followed by unlockOrientation() cancel
112 // the lockOrientation().
113 TEST_F(ScreenOrientationDispatcherTest
, CancelPending_Unlocking
) {
114 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
115 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
116 new MockLockOrientationCallback(&callback_results
));
119 EXPECT_FALSE(callback_results
.succeeded_
);
120 EXPECT_TRUE(callback_results
.failed_
);
121 EXPECT_EQ(blink::WebLockOrientationErrorCanceled
, callback_results
.error_
);
124 // Test that calling lockOrientation() twice cancel the first lockOrientation().
125 TEST_F(ScreenOrientationDispatcherTest
, CancelPending_DoubleLock
) {
126 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
127 // We create the object to prevent leaks but never actually use it.
128 MockLockOrientationCallback::LockOrientationResultHolder callback_results2
;
130 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
131 new MockLockOrientationCallback(&callback_results
));
132 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
133 new MockLockOrientationCallback(&callback_results2
));
135 EXPECT_FALSE(callback_results
.succeeded_
);
136 EXPECT_TRUE(callback_results
.failed_
);
137 EXPECT_EQ(blink::WebLockOrientationErrorCanceled
, callback_results
.error_
);
140 // Test that when a LockError message is received, the request is set as failed
141 // with the correct values.
142 TEST_F(ScreenOrientationDispatcherTest
, LockRequest_Error
) {
143 std::list
<blink::WebLockOrientationError
> errors
;
144 errors
.push_back(blink::WebLockOrientationErrorNotAvailable
);
146 blink::WebLockOrientationErrorFullScreenRequired
);
147 errors
.push_back(blink::WebLockOrientationErrorCanceled
);
149 for (std::list
<blink::WebLockOrientationError
>::const_iterator
150 it
= errors
.begin(); it
!= errors
.end(); ++it
) {
151 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
152 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
153 new MockLockOrientationCallback(&callback_results
));
155 int request_id
= GetFirstLockRequestIdFromSink();
157 ScreenOrientationMsg_LockError(routing_id(), request_id
, *it
));
159 EXPECT_FALSE(callback_results
.succeeded_
);
160 EXPECT_TRUE(callback_results
.failed_
);
161 EXPECT_EQ(*it
, callback_results
.error_
);
163 sink().ClearMessages();
167 // Test that when a LockSuccess message is received, the request is set as
169 TEST_F(ScreenOrientationDispatcherTest
, LockRequest_Success
) {
170 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
171 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
172 new MockLockOrientationCallback(&callback_results
));
174 int request_id
= GetFirstLockRequestIdFromSink();
175 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
178 EXPECT_TRUE(callback_results
.succeeded_
);
179 EXPECT_FALSE(callback_results
.failed_
);
181 sink().ClearMessages();
184 // Test an edge case: a LockSuccess is received but it matches no pending
186 TEST_F(ScreenOrientationDispatcherTest
, SuccessForUnknownRequest
) {
187 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
188 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
189 new MockLockOrientationCallback(&callback_results
));
191 int request_id
= GetFirstLockRequestIdFromSink();
192 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
195 EXPECT_FALSE(callback_results
.succeeded_
);
196 EXPECT_FALSE(callback_results
.failed_
);
199 // Test an edge case: a LockError is received but it matches no pending
201 TEST_F(ScreenOrientationDispatcherTest
, ErrorForUnknownRequest
) {
202 MockLockOrientationCallback::LockOrientationResultHolder callback_results
;
203 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
204 new MockLockOrientationCallback(&callback_results
));
206 int request_id
= GetFirstLockRequestIdFromSink();
207 OnMessageReceived(ScreenOrientationMsg_LockError(
208 routing_id(), request_id
+ 1, blink::WebLockOrientationErrorCanceled
));
210 EXPECT_FALSE(callback_results
.succeeded_
);
211 EXPECT_FALSE(callback_results
.failed_
);
214 // Test the following scenario:
215 // - request1 is received by the dispatcher;
216 // - request2 is received by the dispatcher;
217 // - request1 is rejected;
218 // - request1 success response is received.
219 // Expected: request1 is still rejected, request2 has not been set as succeeded.
220 TEST_F(ScreenOrientationDispatcherTest
, RaceScenario
) {
221 MockLockOrientationCallback::LockOrientationResultHolder callback_results1
;
222 MockLockOrientationCallback::LockOrientationResultHolder callback_results2
;
224 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary
,
225 new MockLockOrientationCallback(&callback_results1
));
226 int request_id1
= GetFirstLockRequestIdFromSink();
228 LockOrientation(blink::WebScreenOrientationLockLandscapePrimary
,
229 new MockLockOrientationCallback(&callback_results2
));
231 // callback_results1 must be rejected, tested in CancelPending_DoubleLock.
233 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(),
236 // First request is still rejected.
237 EXPECT_FALSE(callback_results1
.succeeded_
);
238 EXPECT_TRUE(callback_results1
.failed_
);
239 EXPECT_EQ(blink::WebLockOrientationErrorCanceled
, callback_results1
.error_
);
241 // Second request is still pending.
242 EXPECT_FALSE(callback_results2
.succeeded_
);
243 EXPECT_FALSE(callback_results2
.failed_
);
246 } // namespace content