OLD | NEW |
| (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 "content/browser/device_sensors/data_fetcher_shared_memory_base.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/process/process_handle.h" | |
9 #include "base/synchronization/waitable_event.h" | |
10 #include "base/threading/thread.h" | |
11 #include "content/common/device_sensors/device_light_hardware_buffer.h" | |
12 #include "content/common/device_sensors/device_motion_hardware_buffer.h" | |
13 #include "content/common/device_sensors/device_orientation_hardware_buffer.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 | |
16 namespace content { | |
17 | |
18 namespace { | |
19 | |
20 class FakeDataFetcher : public DataFetcherSharedMemoryBase { | |
21 public: | |
22 FakeDataFetcher() | |
23 : start_light_(false, false), | |
24 start_motion_(false, false), | |
25 start_orientation_(false, false), | |
26 stop_light_(false, false), | |
27 stop_motion_(false, false), | |
28 stop_orientation_(false, false), | |
29 updated_light_(false, false), | |
30 updated_motion_(false, false), | |
31 updated_orientation_(false, false), | |
32 light_buffer_(nullptr), | |
33 motion_buffer_(nullptr), | |
34 orientation_buffer_(nullptr) {} | |
35 ~FakeDataFetcher() override {} | |
36 | |
37 bool Init(ConsumerType consumer_type, void* buffer) { | |
38 EXPECT_TRUE(buffer); | |
39 | |
40 switch (consumer_type) { | |
41 case CONSUMER_TYPE_MOTION: | |
42 motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer); | |
43 break; | |
44 case CONSUMER_TYPE_ORIENTATION: | |
45 orientation_buffer_ = | |
46 static_cast<DeviceOrientationHardwareBuffer*>(buffer); | |
47 break; | |
48 case CONSUMER_TYPE_LIGHT: | |
49 light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer); | |
50 break; | |
51 default: | |
52 return false; | |
53 } | |
54 return true; | |
55 } | |
56 | |
57 void UpdateLight() { | |
58 DeviceLightHardwareBuffer* buffer = GetLightBuffer(); | |
59 ASSERT_TRUE(buffer); | |
60 buffer->seqlock.WriteBegin(); | |
61 buffer->data.value = 100; | |
62 buffer->seqlock.WriteEnd(); | |
63 updated_light_.Signal(); | |
64 } | |
65 | |
66 void UpdateMotion() { | |
67 DeviceMotionHardwareBuffer* buffer = GetMotionBuffer(); | |
68 ASSERT_TRUE(buffer); | |
69 buffer->seqlock.WriteBegin(); | |
70 buffer->data.interval = kInertialSensorIntervalMicroseconds / 1000.; | |
71 buffer->seqlock.WriteEnd(); | |
72 updated_motion_.Signal(); | |
73 } | |
74 | |
75 void UpdateOrientation() { | |
76 DeviceOrientationHardwareBuffer* buffer = GetOrientationBuffer(); | |
77 ASSERT_TRUE(buffer); | |
78 buffer->seqlock.WriteBegin(); | |
79 buffer->data.alpha = 1; | |
80 buffer->seqlock.WriteEnd(); | |
81 updated_orientation_.Signal(); | |
82 } | |
83 | |
84 DeviceLightHardwareBuffer* GetLightBuffer() const { return light_buffer_; } | |
85 | |
86 DeviceMotionHardwareBuffer* GetMotionBuffer() const { | |
87 return motion_buffer_; | |
88 } | |
89 | |
90 DeviceOrientationHardwareBuffer* GetOrientationBuffer() const { | |
91 return orientation_buffer_; | |
92 } | |
93 | |
94 void WaitForStart(ConsumerType consumer_type) { | |
95 switch (consumer_type) { | |
96 case CONSUMER_TYPE_MOTION: | |
97 start_motion_.Wait(); | |
98 break; | |
99 case CONSUMER_TYPE_ORIENTATION: | |
100 start_orientation_.Wait(); | |
101 break; | |
102 case CONSUMER_TYPE_LIGHT: | |
103 start_light_.Wait(); | |
104 break; | |
105 } | |
106 } | |
107 | |
108 void WaitForStop(ConsumerType consumer_type) { | |
109 switch (consumer_type) { | |
110 case CONSUMER_TYPE_MOTION: | |
111 stop_motion_.Wait(); | |
112 break; | |
113 case CONSUMER_TYPE_ORIENTATION: | |
114 stop_orientation_.Wait(); | |
115 break; | |
116 case CONSUMER_TYPE_LIGHT: | |
117 stop_light_.Wait(); | |
118 break; | |
119 } | |
120 } | |
121 | |
122 void WaitForUpdate(ConsumerType consumer_type) { | |
123 switch (consumer_type) { | |
124 case CONSUMER_TYPE_MOTION: | |
125 updated_motion_.Wait(); | |
126 break; | |
127 case CONSUMER_TYPE_ORIENTATION: | |
128 updated_orientation_.Wait(); | |
129 break; | |
130 case CONSUMER_TYPE_LIGHT: | |
131 updated_light_.Wait(); | |
132 break; | |
133 } | |
134 } | |
135 | |
136 protected: | |
137 base::WaitableEvent start_light_; | |
138 base::WaitableEvent start_motion_; | |
139 base::WaitableEvent start_orientation_; | |
140 base::WaitableEvent stop_light_; | |
141 base::WaitableEvent stop_motion_; | |
142 base::WaitableEvent stop_orientation_; | |
143 base::WaitableEvent updated_light_; | |
144 base::WaitableEvent updated_motion_; | |
145 base::WaitableEvent updated_orientation_; | |
146 | |
147 private: | |
148 DeviceLightHardwareBuffer* light_buffer_; | |
149 DeviceMotionHardwareBuffer* motion_buffer_; | |
150 DeviceOrientationHardwareBuffer* orientation_buffer_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher); | |
153 }; | |
154 | |
155 class FakeNonPollingDataFetcher : public FakeDataFetcher { | |
156 public: | |
157 FakeNonPollingDataFetcher() { } | |
158 ~FakeNonPollingDataFetcher() override {} | |
159 | |
160 bool Start(ConsumerType consumer_type, void* buffer) override { | |
161 Init(consumer_type, buffer); | |
162 switch (consumer_type) { | |
163 case CONSUMER_TYPE_MOTION: | |
164 UpdateMotion(); | |
165 start_motion_.Signal(); | |
166 break; | |
167 case CONSUMER_TYPE_ORIENTATION: | |
168 UpdateOrientation(); | |
169 start_orientation_.Signal(); | |
170 break; | |
171 case CONSUMER_TYPE_LIGHT: | |
172 UpdateLight(); | |
173 start_light_.Signal(); | |
174 break; | |
175 default: | |
176 return false; | |
177 } | |
178 return true; | |
179 } | |
180 | |
181 bool Stop(ConsumerType consumer_type) override { | |
182 switch (consumer_type) { | |
183 case CONSUMER_TYPE_MOTION: | |
184 stop_motion_.Signal(); | |
185 break; | |
186 case CONSUMER_TYPE_ORIENTATION: | |
187 stop_orientation_.Signal(); | |
188 break; | |
189 case CONSUMER_TYPE_LIGHT: | |
190 stop_light_.Signal(); | |
191 break; | |
192 default: | |
193 return false; | |
194 } | |
195 return true; | |
196 } | |
197 | |
198 void Fetch(unsigned consumer_bitmask) override { | |
199 FAIL() << "fetch should not be called, " | |
200 << "because this is a non-polling fetcher"; | |
201 } | |
202 | |
203 FetcherType GetType() const override { return FakeDataFetcher::GetType(); } | |
204 | |
205 private: | |
206 DISALLOW_COPY_AND_ASSIGN(FakeNonPollingDataFetcher); | |
207 }; | |
208 | |
209 class FakePollingDataFetcher : public FakeDataFetcher { | |
210 public: | |
211 FakePollingDataFetcher() { } | |
212 ~FakePollingDataFetcher() override {} | |
213 | |
214 bool Start(ConsumerType consumer_type, void* buffer) override { | |
215 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); | |
216 | |
217 Init(consumer_type, buffer); | |
218 switch (consumer_type) { | |
219 case CONSUMER_TYPE_MOTION: | |
220 start_motion_.Signal(); | |
221 break; | |
222 case CONSUMER_TYPE_ORIENTATION: | |
223 start_orientation_.Signal(); | |
224 break; | |
225 case CONSUMER_TYPE_LIGHT: | |
226 start_light_.Signal(); | |
227 break; | |
228 default: | |
229 return false; | |
230 } | |
231 return true; | |
232 } | |
233 | |
234 bool Stop(ConsumerType consumer_type) override { | |
235 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); | |
236 | |
237 switch (consumer_type) { | |
238 case CONSUMER_TYPE_MOTION: | |
239 stop_motion_.Signal(); | |
240 break; | |
241 case CONSUMER_TYPE_ORIENTATION: | |
242 stop_orientation_.Signal(); | |
243 break; | |
244 case CONSUMER_TYPE_LIGHT: | |
245 stop_light_.Signal(); | |
246 break; | |
247 default: | |
248 return false; | |
249 } | |
250 return true; | |
251 } | |
252 | |
253 void Fetch(unsigned consumer_bitmask) override { | |
254 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); | |
255 EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION || | |
256 consumer_bitmask & CONSUMER_TYPE_MOTION || | |
257 consumer_bitmask & CONSUMER_TYPE_LIGHT); | |
258 | |
259 if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION) | |
260 UpdateOrientation(); | |
261 if (consumer_bitmask & CONSUMER_TYPE_MOTION) | |
262 UpdateMotion(); | |
263 if (consumer_bitmask & CONSUMER_TYPE_LIGHT) | |
264 UpdateLight(); | |
265 } | |
266 | |
267 FetcherType GetType() const override { return FETCHER_TYPE_POLLING_CALLBACK; } | |
268 | |
269 private: | |
270 DISALLOW_COPY_AND_ASSIGN(FakePollingDataFetcher); | |
271 }; | |
272 | |
273 class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher { | |
274 public: | |
275 FakeZeroDelayPollingDataFetcher() { } | |
276 ~FakeZeroDelayPollingDataFetcher() override {} | |
277 | |
278 bool Start(ConsumerType consumer_type, void* buffer) override { | |
279 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); | |
280 | |
281 Init(consumer_type, buffer); | |
282 switch (consumer_type) { | |
283 case CONSUMER_TYPE_MOTION: | |
284 start_motion_.Signal(); | |
285 break; | |
286 case CONSUMER_TYPE_ORIENTATION: | |
287 start_orientation_.Signal(); | |
288 break; | |
289 case CONSUMER_TYPE_LIGHT: | |
290 start_light_.Signal(); | |
291 break; | |
292 default: | |
293 return false; | |
294 } | |
295 return true; | |
296 } | |
297 | |
298 bool Stop(ConsumerType consumer_type) override { | |
299 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); | |
300 | |
301 switch (consumer_type) { | |
302 case CONSUMER_TYPE_MOTION: | |
303 stop_motion_.Signal(); | |
304 break; | |
305 case CONSUMER_TYPE_ORIENTATION: | |
306 stop_orientation_.Signal(); | |
307 break; | |
308 case CONSUMER_TYPE_LIGHT: | |
309 stop_light_.Signal(); | |
310 break; | |
311 default: | |
312 return false; | |
313 } | |
314 return true; | |
315 } | |
316 | |
317 void Fetch(unsigned consumer_bitmask) override { | |
318 FAIL() << "fetch should not be called"; | |
319 } | |
320 | |
321 FetcherType GetType() const override { return FETCHER_TYPE_SEPARATE_THREAD; } | |
322 | |
323 bool IsPollingTimerRunningForTesting() const { | |
324 return FakeDataFetcher::IsPollingTimerRunningForTesting(); | |
325 } | |
326 | |
327 private: | |
328 DISALLOW_COPY_AND_ASSIGN(FakeZeroDelayPollingDataFetcher); | |
329 }; | |
330 | |
331 | |
332 TEST(DataFetcherSharedMemoryBaseTest, DoesStartMotion) { | |
333 FakeNonPollingDataFetcher fake_data_fetcher; | |
334 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, | |
335 fake_data_fetcher.GetType()); | |
336 | |
337 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION)); | |
338 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); | |
339 | |
340 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000., | |
341 fake_data_fetcher.GetMotionBuffer()->data.interval); | |
342 | |
343 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); | |
344 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); | |
345 } | |
346 | |
347 TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) { | |
348 FakeNonPollingDataFetcher fake_data_fetcher; | |
349 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, | |
350 fake_data_fetcher.GetType()); | |
351 | |
352 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( | |
353 CONSUMER_TYPE_ORIENTATION)); | |
354 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); | |
355 | |
356 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); | |
357 | |
358 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); | |
359 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); | |
360 } | |
361 | |
362 TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) { | |
363 FakeNonPollingDataFetcher fake_data_fetcher; | |
364 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT, | |
365 fake_data_fetcher.GetType()); | |
366 | |
367 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT)); | |
368 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT); | |
369 | |
370 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value); | |
371 | |
372 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT); | |
373 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT); | |
374 } | |
375 | |
376 TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) { | |
377 FakePollingDataFetcher fake_data_fetcher; | |
378 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, | |
379 fake_data_fetcher.GetType()); | |
380 | |
381 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION)); | |
382 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); | |
383 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION); | |
384 | |
385 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000., | |
386 fake_data_fetcher.GetMotionBuffer()->data.interval); | |
387 | |
388 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); | |
389 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); | |
390 } | |
391 | |
392 TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) { | |
393 FakePollingDataFetcher fake_data_fetcher; | |
394 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, | |
395 fake_data_fetcher.GetType()); | |
396 | |
397 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( | |
398 CONSUMER_TYPE_ORIENTATION)); | |
399 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); | |
400 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION); | |
401 | |
402 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); | |
403 | |
404 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); | |
405 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); | |
406 } | |
407 | |
408 TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) { | |
409 FakePollingDataFetcher fake_data_fetcher; | |
410 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, | |
411 fake_data_fetcher.GetType()); | |
412 | |
413 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT)); | |
414 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT); | |
415 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_LIGHT); | |
416 | |
417 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value); | |
418 | |
419 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT); | |
420 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT); | |
421 } | |
422 | |
423 TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) { | |
424 FakePollingDataFetcher fake_data_fetcher; | |
425 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, | |
426 fake_data_fetcher.GetType()); | |
427 | |
428 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( | |
429 CONSUMER_TYPE_ORIENTATION)); | |
430 base::SharedMemoryHandle handle_orientation = | |
431 fake_data_fetcher.GetSharedMemoryHandleForProcess( | |
432 CONSUMER_TYPE_ORIENTATION, base::GetCurrentProcessHandle()); | |
433 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_orientation)); | |
434 | |
435 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( | |
436 CONSUMER_TYPE_MOTION)); | |
437 base::SharedMemoryHandle handle_motion = | |
438 fake_data_fetcher.GetSharedMemoryHandleForProcess( | |
439 CONSUMER_TYPE_MOTION, base::GetCurrentProcessHandle()); | |
440 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_motion)); | |
441 | |
442 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); | |
443 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION); | |
444 | |
445 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION); | |
446 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION); | |
447 | |
448 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha); | |
449 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000., | |
450 fake_data_fetcher.GetMotionBuffer()->data.interval); | |
451 | |
452 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); | |
453 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION); | |
454 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); | |
455 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION); | |
456 } | |
457 | |
458 TEST(DataFetcherSharedMemoryBaseTest, DoesNotPollZeroDelay) { | |
459 FakeZeroDelayPollingDataFetcher fake_data_fetcher; | |
460 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_SEPARATE_THREAD, | |
461 fake_data_fetcher.GetType()); | |
462 | |
463 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData( | |
464 CONSUMER_TYPE_ORIENTATION)); | |
465 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION); | |
466 | |
467 EXPECT_FALSE(fake_data_fetcher.IsPollingTimerRunningForTesting()); | |
468 EXPECT_EQ(0, fake_data_fetcher.GetOrientationBuffer()->data.alpha); | |
469 | |
470 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); | |
471 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); | |
472 } | |
473 | |
474 | |
475 } // namespace | |
476 | |
477 } // namespace content | |
OLD | NEW |