| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h" | 5 #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <tuple> | 9 #include <tuple> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "content/common/screen_orientation_messages.h" | 12 #include "content/public/test/render_view_test.h" |
| 13 #include "content/public/test/test_utils.h" | 13 #include "content/public/test/test_utils.h" |
| 14 #include "ipc/ipc_test_sink.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebLockO
rientationCallback.h" | 14 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebLockO
rientationCallback.h" |
| 17 | 15 |
| 18 namespace content { | 16 namespace content { |
| 19 | 17 |
| 18 using LockOrientationCallback = |
| 19 mojom::ScreenOrientation::LockOrientationCallback; |
| 20 using LockResult = ::blink::mojom::ScreenOrientationLockResult; |
| 21 |
| 20 // MockLockOrientationCallback is an implementation of | 22 // MockLockOrientationCallback is an implementation of |
| 21 // WebLockOrientationCallback and takes a LockOrientationResultHolder* as a | 23 // WebLockOrientationCallback and takes a LockOrientationResultHolder* as a |
| 22 // parameter when being constructed. The |results_| pointer is owned by the | 24 // parameter when being constructed. The |results_| pointer is owned by the |
| 23 // caller and not by the callback object. The intent being that as soon as the | 25 // caller and not by the callback object. The intent being that as soon as the |
| 24 // callback is resolved, it will be killed so we use the | 26 // callback is resolved, it will be killed so we use the |
| 25 // LockOrientationResultHolder to know in which state the callback object is at | 27 // LockOrientationResultHolder to know in which state the callback object is at |
| 26 // any time. | 28 // any time. |
| 27 class MockLockOrientationCallback : public blink::WebLockOrientationCallback { | 29 class MockLockOrientationCallback : public blink::WebLockOrientationCallback { |
| 28 public: | 30 public: |
| 29 struct LockOrientationResultHolder { | 31 struct LockOrientationResultHolder { |
| 30 LockOrientationResultHolder() | 32 LockOrientationResultHolder() : succeeded_(false), failed_(false) {} |
| 31 : succeeded_(false), failed_(false) {} | |
| 32 | 33 |
| 33 bool succeeded_; | 34 bool succeeded_; |
| 34 bool failed_; | 35 bool failed_; |
| 35 blink::WebLockOrientationError error_; | 36 blink::WebLockOrientationError error_; |
| 36 }; | 37 }; |
| 37 | 38 |
| 38 explicit MockLockOrientationCallback(LockOrientationResultHolder* results) | 39 explicit MockLockOrientationCallback(LockOrientationResultHolder* results) |
| 39 : results_(results) {} | 40 : results_(results) {} |
| 40 | 41 |
| 41 void onSuccess() override { results_->succeeded_ = true; } | 42 void onSuccess() override { results_->succeeded_ = true; } |
| 42 | 43 |
| 43 void onError(blink::WebLockOrientationError error) override { | 44 void onError(blink::WebLockOrientationError error) override { |
| 44 results_->failed_ = true; | 45 results_->failed_ = true; |
| 45 results_->error_ = error; | 46 results_->error_ = error; |
| 46 } | 47 } |
| 47 | 48 |
| 48 private: | 49 private: |
| 49 ~MockLockOrientationCallback() override {} | 50 ~MockLockOrientationCallback() override {} |
| 50 | 51 |
| 51 LockOrientationResultHolder* results_; | 52 LockOrientationResultHolder* results_; |
| 52 }; | 53 }; |
| 53 | 54 |
| 54 class ScreenOrientationDispatcherWithSink : public ScreenOrientationDispatcher { | 55 class ScreenOrientationDispatcherTest : public RenderViewTest { |
| 55 public: | |
| 56 explicit ScreenOrientationDispatcherWithSink(IPC::TestSink* sink) | |
| 57 :ScreenOrientationDispatcher(NULL) , sink_(sink) { | |
| 58 } | |
| 59 | |
| 60 bool Send(IPC::Message* message) override { return sink_->Send(message); } | |
| 61 | |
| 62 IPC::TestSink* sink_; | |
| 63 }; | |
| 64 | |
| 65 class ScreenOrientationDispatcherTest : public testing::Test { | |
| 66 protected: | 56 protected: |
| 67 void SetUp() override { | 57 void SetUp() override { |
| 68 dispatcher_.reset(new ScreenOrientationDispatcherWithSink(&sink_)); | 58 RenderViewTest::SetUp(); |
| 69 } | 59 dispatcher_.reset(new ScreenOrientationDispatcher(nullptr)); |
| 70 | 60 ScreenOrientationAssociatedPtr screen_orientation; |
| 71 int GetFirstLockRequestIdFromSink() { | 61 mojo::GetDummyProxyForTesting(&screen_orientation); |
| 72 const IPC::Message* msg = sink().GetFirstMessageMatching( | 62 dispatcher_->setScreenOrientationForTests(screen_orientation); |
| 73 ScreenOrientationHostMsg_LockRequest::ID); | |
| 74 EXPECT_TRUE(msg != NULL); | |
| 75 | |
| 76 std::tuple<blink::WebScreenOrientationLockType, int> params; | |
| 77 ScreenOrientationHostMsg_LockRequest::Read(msg, ¶ms); | |
| 78 return std::get<1>(params); | |
| 79 } | |
| 80 | |
| 81 IPC::TestSink& sink() { | |
| 82 return sink_; | |
| 83 } | 63 } |
| 84 | 64 |
| 85 void LockOrientation(blink::WebScreenOrientationLockType orientation, | 65 void LockOrientation(blink::WebScreenOrientationLockType orientation, |
| 86 blink::WebLockOrientationCallback* callback) { | 66 blink::WebLockOrientationCallback* callback) { |
| 87 dispatcher_->lockOrientation(orientation, callback); | 67 dispatcher_->lockOrientation(orientation, callback); |
| 88 } | 68 } |
| 89 | 69 |
| 90 void UnlockOrientation() { | 70 void UnlockOrientation() { dispatcher_->unlockOrientation(); } |
| 91 dispatcher_->unlockOrientation(); | 71 |
| 72 void RunLockResultCallback(LockResult result) { |
| 73 dispatcher_->OnLockOrientationResult(dispatcher_->getRequestIdForTests(), |
| 74 result); |
| 92 } | 75 } |
| 93 | 76 |
| 94 void OnMessageReceived(const IPC::Message& message) { | |
| 95 dispatcher_->OnMessageReceived(message); | |
| 96 } | |
| 97 | |
| 98 int routing_id() const { | |
| 99 // We return a fake routing_id() in the context of this test. | |
| 100 return 0; | |
| 101 } | |
| 102 | |
| 103 IPC::TestSink sink_; | |
| 104 std::unique_ptr<ScreenOrientationDispatcher> dispatcher_; | 77 std::unique_ptr<ScreenOrientationDispatcher> dispatcher_; |
| 105 }; | 78 }; |
| 106 | 79 |
| 107 // Test that calling lockOrientation() followed by unlockOrientation() cancel | 80 // Test that calling lockOrientation() followed by unlockOrientation() cancel |
| 108 // the lockOrientation(). | 81 // the lockOrientation(). |
| 109 TEST_F(ScreenOrientationDispatcherTest, CancelPending_Unlocking) { | 82 TEST_F(ScreenOrientationDispatcherTest, CancelPending_Unlocking) { |
| 110 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | 83 MockLockOrientationCallback::LockOrientationResultHolder callback_results; |
| 84 |
| 111 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 85 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 112 new MockLockOrientationCallback(&callback_results)); | 86 new MockLockOrientationCallback(&callback_results)); |
| 113 UnlockOrientation(); | 87 UnlockOrientation(); |
| 114 | 88 |
| 115 EXPECT_FALSE(callback_results.succeeded_); | 89 EXPECT_FALSE(callback_results.succeeded_); |
| 116 EXPECT_TRUE(callback_results.failed_); | 90 EXPECT_TRUE(callback_results.failed_); |
| 117 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_); | 91 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_); |
| 118 } | 92 } |
| 119 | 93 |
| 120 // Test that calling lockOrientation() twice cancel the first lockOrientation(). | 94 // Test that calling lockOrientation() twice cancel the first lockOrientation(). |
| 121 TEST_F(ScreenOrientationDispatcherTest, CancelPending_DoubleLock) { | 95 TEST_F(ScreenOrientationDispatcherTest, CancelPending_DoubleLock) { |
| 122 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | 96 MockLockOrientationCallback::LockOrientationResultHolder callback_results; |
| 123 // We create the object to prevent leaks but never actually use it. | 97 // We create the object to prevent leaks but never actually use it. |
| 124 MockLockOrientationCallback::LockOrientationResultHolder callback_results2; | 98 MockLockOrientationCallback::LockOrientationResultHolder callback_results2; |
| 125 | 99 |
| 126 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 100 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 127 new MockLockOrientationCallback(&callback_results)); | 101 new MockLockOrientationCallback(&callback_results)); |
| 102 |
| 128 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 103 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 129 new MockLockOrientationCallback(&callback_results2)); | 104 new MockLockOrientationCallback(&callback_results2)); |
| 130 | 105 |
| 131 EXPECT_FALSE(callback_results.succeeded_); | 106 EXPECT_FALSE(callback_results.succeeded_); |
| 132 EXPECT_TRUE(callback_results.failed_); | 107 EXPECT_TRUE(callback_results.failed_); |
| 133 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_); | 108 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results.error_); |
| 134 } | 109 } |
| 135 | 110 |
| 136 // Test that when a LockError message is received, the request is set as failed | 111 // Test that when a LockError message is received, the request is set as failed |
| 137 // with the correct values. | 112 // with the correct values. |
| 138 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Error) { | 113 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Error) { |
| 139 std::list<blink::WebLockOrientationError> errors; | 114 std::map<LockResult, blink::WebLockOrientationError> errors; |
| 140 errors.push_back(blink::WebLockOrientationErrorNotAvailable); | 115 errors[LockResult::SCREEN_ORIENTATION_LOCK_RESULT_ERROR_NOT_AVAILABLE] = |
| 141 errors.push_back( | 116 blink::WebLockOrientationErrorNotAvailable; |
| 142 blink::WebLockOrientationErrorFullscreenRequired); | 117 errors[LockResult::SCREEN_ORIENTATION_LOCK_RESULT_ERROR_FULLSCREEN_REQUIRED] = |
| 143 errors.push_back(blink::WebLockOrientationErrorCanceled); | 118 blink::WebLockOrientationErrorFullscreenRequired; |
| 119 errors[LockResult::SCREEN_ORIENTATION_LOCK_RESULT_ERROR_CANCELED] = |
| 120 blink::WebLockOrientationErrorCanceled; |
| 144 | 121 |
| 145 for (std::list<blink::WebLockOrientationError>::const_iterator | 122 for (std::map<LockResult, blink::WebLockOrientationError>::const_iterator it = |
| 146 it = errors.begin(); it != errors.end(); ++it) { | 123 errors.begin(); |
| 124 it != errors.end(); ++it) { |
| 147 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | 125 MockLockOrientationCallback::LockOrientationResultHolder callback_results; |
| 148 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 126 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 149 new MockLockOrientationCallback(&callback_results)); | 127 new MockLockOrientationCallback(&callback_results)); |
| 150 | 128 RunLockResultCallback(it->first); |
| 151 int request_id = GetFirstLockRequestIdFromSink(); | |
| 152 OnMessageReceived( | |
| 153 ScreenOrientationMsg_LockError(routing_id(), request_id, *it)); | |
| 154 | |
| 155 EXPECT_FALSE(callback_results.succeeded_); | 129 EXPECT_FALSE(callback_results.succeeded_); |
| 156 EXPECT_TRUE(callback_results.failed_); | 130 EXPECT_TRUE(callback_results.failed_); |
| 157 EXPECT_EQ(*it, callback_results.error_); | 131 EXPECT_EQ(it->second, callback_results.error_); |
| 158 | |
| 159 sink().ClearMessages(); | |
| 160 } | 132 } |
| 161 } | 133 } |
| 162 | 134 |
| 163 // Test that when a LockSuccess message is received, the request is set as | 135 // Test that when a LockSuccess message is received, the request is set as |
| 164 // succeeded. | 136 // succeeded. |
| 165 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Success) { | 137 TEST_F(ScreenOrientationDispatcherTest, LockRequest_Success) { |
| 166 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | 138 MockLockOrientationCallback::LockOrientationResultHolder callback_results; |
| 167 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 139 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 168 new MockLockOrientationCallback(&callback_results)); | 140 new MockLockOrientationCallback(&callback_results)); |
| 169 | 141 |
| 170 int request_id = GetFirstLockRequestIdFromSink(); | 142 RunLockResultCallback(LockResult::SCREEN_ORIENTATION_LOCK_RESULT_SUCCESS); |
| 171 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(), | |
| 172 request_id)); | |
| 173 | 143 |
| 174 EXPECT_TRUE(callback_results.succeeded_); | 144 EXPECT_TRUE(callback_results.succeeded_); |
| 175 EXPECT_FALSE(callback_results.failed_); | 145 EXPECT_FALSE(callback_results.failed_); |
| 176 | |
| 177 sink().ClearMessages(); | |
| 178 } | |
| 179 | |
| 180 // Test an edge case: a LockSuccess is received but it matches no pending | |
| 181 // callback. | |
| 182 TEST_F(ScreenOrientationDispatcherTest, SuccessForUnknownRequest) { | |
| 183 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | |
| 184 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | |
| 185 new MockLockOrientationCallback(&callback_results)); | |
| 186 | |
| 187 int request_id = GetFirstLockRequestIdFromSink(); | |
| 188 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(), | |
| 189 request_id + 1)); | |
| 190 | |
| 191 EXPECT_FALSE(callback_results.succeeded_); | |
| 192 EXPECT_FALSE(callback_results.failed_); | |
| 193 } | |
| 194 | |
| 195 // Test an edge case: a LockError is received but it matches no pending | |
| 196 // callback. | |
| 197 TEST_F(ScreenOrientationDispatcherTest, ErrorForUnknownRequest) { | |
| 198 MockLockOrientationCallback::LockOrientationResultHolder callback_results; | |
| 199 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | |
| 200 new MockLockOrientationCallback(&callback_results)); | |
| 201 | |
| 202 int request_id = GetFirstLockRequestIdFromSink(); | |
| 203 OnMessageReceived(ScreenOrientationMsg_LockError( | |
| 204 routing_id(), request_id + 1, blink::WebLockOrientationErrorCanceled)); | |
| 205 | |
| 206 EXPECT_FALSE(callback_results.succeeded_); | |
| 207 EXPECT_FALSE(callback_results.failed_); | |
| 208 } | 146 } |
| 209 | 147 |
| 210 // Test the following scenario: | 148 // Test the following scenario: |
| 211 // - request1 is received by the dispatcher; | 149 // - request1 is received by the dispatcher; |
| 212 // - request2 is received by the dispatcher; | 150 // - request2 is received by the dispatcher; |
| 213 // - request1 is rejected; | 151 // - request1 is rejected; |
| 214 // - request1 success response is received. | 152 // - request1 success response is received. |
| 215 // Expected: request1 is still rejected, request2 has not been set as succeeded. | 153 // Expected: request1 is still rejected, request2 has not been set as succeeded. |
| 216 TEST_F(ScreenOrientationDispatcherTest, RaceScenario) { | 154 TEST_F(ScreenOrientationDispatcherTest, RaceScenario) { |
| 217 MockLockOrientationCallback::LockOrientationResultHolder callback_results1; | 155 MockLockOrientationCallback::LockOrientationResultHolder callback_results1; |
| 218 MockLockOrientationCallback::LockOrientationResultHolder callback_results2; | 156 MockLockOrientationCallback::LockOrientationResultHolder callback_results2; |
| 219 | 157 |
| 220 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, | 158 LockOrientation(blink::WebScreenOrientationLockPortraitPrimary, |
| 221 new MockLockOrientationCallback(&callback_results1)); | 159 new MockLockOrientationCallback(&callback_results1)); |
| 222 int request_id1 = GetFirstLockRequestIdFromSink(); | |
| 223 | 160 |
| 224 LockOrientation(blink::WebScreenOrientationLockLandscapePrimary, | 161 LockOrientation(blink::WebScreenOrientationLockLandscapePrimary, |
| 225 new MockLockOrientationCallback(&callback_results2)); | 162 new MockLockOrientationCallback(&callback_results2)); |
| 226 | 163 |
| 227 // callback_results1 must be rejected, tested in CancelPending_DoubleLock. | |
| 228 | |
| 229 OnMessageReceived(ScreenOrientationMsg_LockSuccess(routing_id(), | |
| 230 request_id1)); | |
| 231 | |
| 232 // First request is still rejected. | 164 // First request is still rejected. |
| 233 EXPECT_FALSE(callback_results1.succeeded_); | 165 EXPECT_FALSE(callback_results1.succeeded_); |
| 234 EXPECT_TRUE(callback_results1.failed_); | 166 EXPECT_TRUE(callback_results1.failed_); |
| 235 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results1.error_); | 167 EXPECT_EQ(blink::WebLockOrientationErrorCanceled, callback_results1.error_); |
| 236 | 168 |
| 237 // Second request is still pending. | 169 // Second request is still pending. |
| 238 EXPECT_FALSE(callback_results2.succeeded_); | 170 EXPECT_FALSE(callback_results2.succeeded_); |
| 239 EXPECT_FALSE(callback_results2.failed_); | 171 EXPECT_FALSE(callback_results2.failed_); |
| 240 } | 172 } |
| 241 | 173 |
| 242 } // namespace content | 174 } // namespace content |
| OLD | NEW |