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

Side by Side Diff: content/browser/device_sensors/device_sensor_browsertest.cc

Issue 2812223006: Replace device_sensor browsertest by service unittest. (Closed)
Patch Set: eliminate "unreachable code" warning. Created 3 years, 8 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 unified diff | Download patch
« no previous file with comments | « content/browser/device_sensors/OWNERS ('k') | content/renderer/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "base/command_line.h"
6 #include "base/macros.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/threading/platform_thread.h"
9 #include "build/build_config.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/content_switches.h"
13 #include "content/public/test/content_browser_test.h"
14 #include "content/public/test/content_browser_test_utils.h"
15 #include "content/public/test/test_navigation_observer.h"
16 #include "content/public/test/test_utils.h"
17 #include "content/shell/browser/shell.h"
18 #include "content/shell/browser/shell_javascript_dialog_manager.h"
19 #include "device/sensors/data_fetcher_shared_memory.h"
20 #include "device/sensors/device_sensor_service.h"
21 #include "device/sensors/public/cpp/device_light_hardware_buffer.h"
22 #include "device/sensors/public/cpp/device_motion_hardware_buffer.h"
23 #include "device/sensors/public/cpp/device_orientation_hardware_buffer.h"
24
25 namespace content {
26
27 namespace {
28
29 class FakeDataFetcher : public device::DataFetcherSharedMemory {
30 public:
31 FakeDataFetcher() : sensor_data_available_(true) {}
32 ~FakeDataFetcher() override {}
33
34 void SetMotionStartedCallback(base::Closure motion_started_callback) {
35 motion_started_callback_ = motion_started_callback;
36 }
37
38 void SetMotionStoppedCallback(base::Closure motion_stopped_callback) {
39 motion_stopped_callback_ = motion_stopped_callback;
40 }
41
42 void SetLightStartedCallback(base::Closure light_started_callback) {
43 light_started_callback_ = light_started_callback;
44 }
45
46 void SetLightStoppedCallback(base::Closure light_stopped_callback) {
47 light_stopped_callback_ = light_stopped_callback;
48 }
49
50 void SetOrientationStartedCallback(
51 base::Closure orientation_started_callback) {
52 orientation_started_callback_ = orientation_started_callback;
53 }
54
55 void SetOrientationStoppedCallback(
56 base::Closure orientation_stopped_callback) {
57 orientation_stopped_callback_ = orientation_stopped_callback;
58 }
59
60 void SetOrientationAbsoluteStartedCallback(
61 base::Closure orientation_absolute_started_callback) {
62 orientation_absolute_started_callback_ =
63 orientation_absolute_started_callback;
64 }
65
66 void SetOrientationAbsoluteStoppedCallback(
67 base::Closure orientation_absolute_stopped_callback) {
68 orientation_absolute_stopped_callback_ =
69 orientation_absolute_stopped_callback;
70 }
71
72 bool Start(device::ConsumerType consumer_type, void* buffer) override {
73 EXPECT_TRUE(buffer);
74
75 switch (consumer_type) {
76 case device::CONSUMER_TYPE_MOTION: {
77 device::DeviceMotionHardwareBuffer* motion_buffer =
78 static_cast<device::DeviceMotionHardwareBuffer*>(buffer);
79 if (sensor_data_available_)
80 UpdateMotion(motion_buffer);
81 SetMotionBufferReady(motion_buffer);
82 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
83 motion_started_callback_);
84 } break;
85 case device::CONSUMER_TYPE_ORIENTATION: {
86 device::DeviceOrientationHardwareBuffer* orientation_buffer =
87 static_cast<device::DeviceOrientationHardwareBuffer*>(buffer);
88 if (sensor_data_available_)
89 UpdateOrientation(orientation_buffer);
90 SetOrientationBufferReady(orientation_buffer);
91 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
92 orientation_started_callback_);
93 } break;
94 case device::CONSUMER_TYPE_ORIENTATION_ABSOLUTE: {
95 device::DeviceOrientationHardwareBuffer* orientation_buffer =
96 static_cast<device::DeviceOrientationHardwareBuffer*>(buffer);
97 if (sensor_data_available_)
98 UpdateOrientationAbsolute(orientation_buffer);
99 SetOrientationBufferReady(orientation_buffer);
100 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
101 orientation_absolute_started_callback_);
102 } break;
103 case device::CONSUMER_TYPE_LIGHT: {
104 device::DeviceLightHardwareBuffer* light_buffer =
105 static_cast<device::DeviceLightHardwareBuffer*>(buffer);
106 UpdateLight(light_buffer,
107 sensor_data_available_
108 ? 100
109 : std::numeric_limits<double>::infinity());
110 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
111 light_started_callback_);
112 } break;
113 default:
114 return false;
115 }
116 return true;
117 }
118
119 bool Stop(device::ConsumerType consumer_type) override {
120 switch (consumer_type) {
121 case device::CONSUMER_TYPE_MOTION:
122 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
123 motion_stopped_callback_);
124 break;
125 case device::CONSUMER_TYPE_ORIENTATION:
126 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
127 orientation_stopped_callback_);
128 break;
129 case device::CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
130 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
131 orientation_absolute_stopped_callback_);
132 break;
133 case device::CONSUMER_TYPE_LIGHT:
134 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
135 light_stopped_callback_);
136 break;
137 default:
138 return false;
139 }
140 return true;
141 }
142
143 void Fetch(unsigned consumer_bitmask) override {
144 FAIL() << "fetch should not be called";
145 }
146
147 FetcherType GetType() const override { return FETCHER_TYPE_DEFAULT; }
148
149 void SetSensorDataAvailable(bool available) {
150 sensor_data_available_ = available;
151 }
152
153 void SetMotionBufferReady(device::DeviceMotionHardwareBuffer* buffer) {
154 buffer->seqlock.WriteBegin();
155 buffer->data.all_available_sensors_are_active = true;
156 buffer->seqlock.WriteEnd();
157 }
158
159 void SetOrientationBufferReady(
160 device::DeviceOrientationHardwareBuffer* buffer) {
161 buffer->seqlock.WriteBegin();
162 buffer->data.all_available_sensors_are_active = true;
163 buffer->seqlock.WriteEnd();
164 }
165
166 void UpdateMotion(device::DeviceMotionHardwareBuffer* buffer) {
167 buffer->seqlock.WriteBegin();
168 buffer->data.acceleration_x = 1;
169 buffer->data.has_acceleration_x = true;
170 buffer->data.acceleration_y = 2;
171 buffer->data.has_acceleration_y = true;
172 buffer->data.acceleration_z = 3;
173 buffer->data.has_acceleration_z = true;
174
175 buffer->data.acceleration_including_gravity_x = 4;
176 buffer->data.has_acceleration_including_gravity_x = true;
177 buffer->data.acceleration_including_gravity_y = 5;
178 buffer->data.has_acceleration_including_gravity_y = true;
179 buffer->data.acceleration_including_gravity_z = 6;
180 buffer->data.has_acceleration_including_gravity_z = true;
181
182 buffer->data.rotation_rate_alpha = 7;
183 buffer->data.has_rotation_rate_alpha = true;
184 buffer->data.rotation_rate_beta = 8;
185 buffer->data.has_rotation_rate_beta = true;
186 buffer->data.rotation_rate_gamma = 9;
187 buffer->data.has_rotation_rate_gamma = true;
188
189 buffer->data.interval = 100;
190 buffer->data.all_available_sensors_are_active = true;
191 buffer->seqlock.WriteEnd();
192 }
193
194 void UpdateOrientation(device::DeviceOrientationHardwareBuffer* buffer) {
195 buffer->seqlock.WriteBegin();
196 buffer->data.alpha = 1;
197 buffer->data.has_alpha = true;
198 buffer->data.beta = 2;
199 buffer->data.has_beta = true;
200 buffer->data.gamma = 3;
201 buffer->data.has_gamma = true;
202 buffer->data.all_available_sensors_are_active = true;
203 buffer->seqlock.WriteEnd();
204 }
205
206 void UpdateOrientationAbsolute(
207 device::DeviceOrientationHardwareBuffer* buffer) {
208 buffer->seqlock.WriteBegin();
209 buffer->data.alpha = 4;
210 buffer->data.has_alpha = true;
211 buffer->data.beta = 5;
212 buffer->data.has_beta = true;
213 buffer->data.gamma = 6;
214 buffer->data.has_gamma = true;
215 buffer->data.absolute = true;
216 buffer->data.all_available_sensors_are_active = true;
217 buffer->seqlock.WriteEnd();
218 }
219
220 void UpdateLight(device::DeviceLightHardwareBuffer* buffer, double lux) {
221 buffer->seqlock.WriteBegin();
222 buffer->data.value = lux;
223 buffer->seqlock.WriteEnd();
224 }
225
226 // The below callbacks should be run on the UI thread.
227 base::Closure motion_started_callback_;
228 base::Closure orientation_started_callback_;
229 base::Closure orientation_absolute_started_callback_;
230 base::Closure light_started_callback_;
231 base::Closure motion_stopped_callback_;
232 base::Closure orientation_stopped_callback_;
233 base::Closure orientation_absolute_stopped_callback_;
234 base::Closure light_stopped_callback_;
235 bool sensor_data_available_;
236
237 private:
238 DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher);
239 };
240
241 class DeviceSensorBrowserTest : public ContentBrowserTest {
242 public:
243 DeviceSensorBrowserTest()
244 : fetcher_(nullptr),
245 io_loop_finished_event_(
246 base::WaitableEvent::ResetPolicy::AUTOMATIC,
247 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
248
249 void SetUpOnMainThread() override {
250 // Initialize the RunLoops now that the main thread has been created.
251 light_started_runloop_.reset(new base::RunLoop());
252 light_stopped_runloop_.reset(new base::RunLoop());
253 motion_started_runloop_.reset(new base::RunLoop());
254 motion_stopped_runloop_.reset(new base::RunLoop());
255 orientation_started_runloop_.reset(new base::RunLoop());
256 orientation_stopped_runloop_.reset(new base::RunLoop());
257 orientation_absolute_started_runloop_.reset(new base::RunLoop());
258 orientation_absolute_stopped_runloop_.reset(new base::RunLoop());
259 #if defined(OS_ANDROID)
260 // On Android, the DeviceSensorService lives on the UI thread.
261 SetUpFetcher();
262 #else
263 // On all other platforms, the DeviceSensorService lives on the IO thread.
264 BrowserThread::PostTask(
265 BrowserThread::IO, FROM_HERE,
266 base::Bind(&DeviceSensorBrowserTest::SetUpOnIOThread,
267 base::Unretained(this)));
268 io_loop_finished_event_.Wait();
269 #endif
270 }
271
272 void SetUpFetcher() {
273 fetcher_ = new FakeDataFetcher();
274 fetcher_->SetLightStartedCallback(light_started_runloop_->QuitClosure());
275 fetcher_->SetLightStoppedCallback(light_stopped_runloop_->QuitClosure());
276 fetcher_->SetMotionStartedCallback(motion_started_runloop_->QuitClosure());
277 fetcher_->SetMotionStoppedCallback(motion_stopped_runloop_->QuitClosure());
278 fetcher_->SetOrientationStartedCallback(
279 orientation_started_runloop_->QuitClosure());
280 fetcher_->SetOrientationStoppedCallback(
281 orientation_stopped_runloop_->QuitClosure());
282 fetcher_->SetOrientationAbsoluteStartedCallback(
283 orientation_absolute_started_runloop_->QuitClosure());
284 fetcher_->SetOrientationAbsoluteStoppedCallback(
285 orientation_absolute_stopped_runloop_->QuitClosure());
286 device::DeviceSensorService::GetInstance()->SetDataFetcherForTesting(
287 fetcher_);
288 }
289
290 void SetUpOnIOThread() {
291 SetUpFetcher();
292 io_loop_finished_event_.Signal();
293 }
294
295 void DelayAndQuit(base::TimeDelta delay) {
296 base::PlatformThread::Sleep(delay);
297 base::MessageLoop::current()->QuitWhenIdle();
298 }
299
300 void WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta delay) {
301 ShellJavaScriptDialogManager* dialog_manager =
302 static_cast<ShellJavaScriptDialogManager*>(
303 shell()->GetJavaScriptDialogManager(shell()->web_contents()));
304
305 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner();
306 dialog_manager->set_dialog_request_callback(
307 base::Bind(&DeviceSensorBrowserTest::DelayAndQuit,
308 base::Unretained(this), delay));
309 runner->Run();
310 }
311
312 void EnableExperimentalFeatures() {
313 // TODO(riju): remove when the DeviceLight feature goes stable.
314 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
315 if (!cmd_line->HasSwitch(switches::kEnableExperimentalWebPlatformFeatures))
316 cmd_line->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
317 }
318
319 FakeDataFetcher* fetcher_;
320
321 // NOTE: These can only be initialized once the main thread has been created
322 // and so must be pointers instead of plain objects.
323 std::unique_ptr<base::RunLoop> light_started_runloop_;
324 std::unique_ptr<base::RunLoop> light_stopped_runloop_;
325 std::unique_ptr<base::RunLoop> motion_started_runloop_;
326 std::unique_ptr<base::RunLoop> motion_stopped_runloop_;
327 std::unique_ptr<base::RunLoop> orientation_started_runloop_;
328 std::unique_ptr<base::RunLoop> orientation_stopped_runloop_;
329 std::unique_ptr<base::RunLoop> orientation_absolute_started_runloop_;
330 std::unique_ptr<base::RunLoop> orientation_absolute_stopped_runloop_;
331
332 private:
333 base::WaitableEvent io_loop_finished_event_;
334 };
335
336 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationTest) {
337 // The test page will register an event handler for orientation events,
338 // expects to get an event with fake values, then removes the event
339 // handler and navigates to #pass.
340 GURL test_url = GetTestUrl("device_sensors", "device_orientation_test.html");
341 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
342
343 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
344 orientation_started_runloop_->Run();
345 orientation_stopped_runloop_->Run();
346 }
347
348 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationAbsoluteTest) {
349 // The test page will register an event handler for absolute orientation
350 // events, expects to get an event with fake values, then removes the event
351 // handler and navigates to #pass.
352 GURL test_url =
353 GetTestUrl("device_sensors", "device_orientation_absolute_test.html");
354 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
355
356 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
357 orientation_absolute_started_runloop_->Run();
358 orientation_absolute_stopped_runloop_->Run();
359 }
360
361 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, LightTest) {
362 // The test page will register an event handler for light events,
363 // expects to get an event with fake values, then removes the event
364 // handler and navigates to #pass.
365 EnableExperimentalFeatures();
366 GURL test_url = GetTestUrl("device_sensors", "device_light_test.html");
367 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
368
369 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
370 light_started_runloop_->Run();
371 light_stopped_runloop_->Run();
372 }
373
374 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionTest) {
375 // The test page will register an event handler for motion events,
376 // expects to get an event with fake values, then removes the event
377 // handler and navigates to #pass.
378 GURL test_url = GetTestUrl("device_sensors", "device_motion_test.html");
379 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
380
381 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
382 motion_started_runloop_->Run();
383 motion_stopped_runloop_->Run();
384 }
385
386 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, LightOneOffInfintyTest) {
387 // The test page registers an event handler for light events and expects
388 // to get an event with value equal to infinity, because no sensor data can
389 // be provided.
390 EnableExperimentalFeatures();
391 fetcher_->SetSensorDataAvailable(false);
392 GURL test_url =
393 GetTestUrl("device_sensors", "device_light_infinity_test.html");
394 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
395
396 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
397 light_started_runloop_->Run();
398 light_stopped_runloop_->Run();
399 }
400
401 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationNullTest) {
402 // The test page registers an event handler for orientation events and
403 // expects to get an event with null values, because no sensor data can be
404 // provided.
405 fetcher_->SetSensorDataAvailable(false);
406 GURL test_url =
407 GetTestUrl("device_sensors", "device_orientation_null_test.html");
408 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
409
410 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
411 orientation_started_runloop_->Run();
412 orientation_stopped_runloop_->Run();
413 }
414
415 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationAbsoluteNullTest) {
416 // The test page registers an event handler for absolute orientation events
417 // and expects to get an event with null values, because no sensor data can be
418 // provided.
419 fetcher_->SetSensorDataAvailable(false);
420 GURL test_url = GetTestUrl("device_sensors",
421 "device_orientation_absolute_null_test.html");
422 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
423
424 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
425 orientation_absolute_started_runloop_->Run();
426 orientation_absolute_stopped_runloop_->Run();
427 }
428
429 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, MotionNullTest) {
430 // The test page registers an event handler for motion events and
431 // expects to get an event with null values, because no sensor data can be
432 // provided.
433 fetcher_->SetSensorDataAvailable(false);
434 GURL test_url = GetTestUrl("device_sensors", "device_motion_null_test.html");
435 NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
436
437 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
438 motion_started_runloop_->Run();
439 motion_stopped_runloop_->Run();
440 }
441
442 IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, NullTestWithAlert) {
443 // The test page registers an event handlers for motion/orientation events and
444 // expects to get events with null values. The test raises a modal alert
445 // dialog with a delay to test that the one-off null-events still propagate to
446 // window after the alert is dismissed and the callbacks are invoked which
447 // eventually navigate to #pass.
448 fetcher_->SetSensorDataAvailable(false);
449 TestNavigationObserver same_tab_observer(shell()->web_contents(), 2);
450
451 GURL test_url =
452 GetTestUrl("device_sensors", "device_sensors_null_test_with_alert.html");
453 shell()->LoadURL(test_url);
454
455 // TODO(timvolodine): investigate if it is possible to test this without
456 // delay, crbug.com/360044.
457 WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(500));
458
459 motion_started_runloop_->Run();
460 motion_stopped_runloop_->Run();
461 orientation_started_runloop_->Run();
462 orientation_stopped_runloop_->Run();
463 same_tab_observer.Wait();
464 EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
465 }
466
467 } // namespace
468
469 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/device_sensors/OWNERS ('k') | content/renderer/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698