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 "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
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"
20 class FakeDataFetcher : public DataFetcherSharedMemoryBase {
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),
34 orientation_buffer_(NULL) {}
35 ~FakeDataFetcher() override {}
37 bool Init(ConsumerType consumer_type, void* buffer) {
40 switch (consumer_type) {
41 case CONSUMER_TYPE_MOTION:
42 motion_buffer_ = static_cast<DeviceMotionHardwareBuffer*>(buffer);
44 case CONSUMER_TYPE_ORIENTATION:
46 static_cast<DeviceOrientationHardwareBuffer*>(buffer);
48 case CONSUMER_TYPE_LIGHT:
49 light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer);
58 DeviceLightHardwareBuffer* buffer = GetLightBuffer();
60 buffer->seqlock.WriteBegin();
61 buffer->data.value = 100;
62 buffer->seqlock.WriteEnd();
63 updated_light_.Signal();
67 DeviceMotionHardwareBuffer* buffer = GetMotionBuffer();
69 buffer->seqlock.WriteBegin();
70 buffer->data.interval = kInertialSensorIntervalMicroseconds / 1000.;
71 buffer->seqlock.WriteEnd();
72 updated_motion_.Signal();
75 void UpdateOrientation() {
76 DeviceOrientationHardwareBuffer* buffer = GetOrientationBuffer();
78 buffer->seqlock.WriteBegin();
79 buffer->data.alpha = 1;
80 buffer->seqlock.WriteEnd();
81 updated_orientation_.Signal();
84 DeviceLightHardwareBuffer* GetLightBuffer() const { return light_buffer_; }
86 DeviceMotionHardwareBuffer* GetMotionBuffer() const {
87 return motion_buffer_;
90 DeviceOrientationHardwareBuffer* GetOrientationBuffer() const {
91 return orientation_buffer_;
94 void WaitForStart(ConsumerType consumer_type) {
95 switch (consumer_type) {
96 case CONSUMER_TYPE_MOTION:
99 case CONSUMER_TYPE_ORIENTATION:
100 start_orientation_.Wait();
102 case CONSUMER_TYPE_LIGHT:
108 void WaitForStop(ConsumerType consumer_type) {
109 switch (consumer_type) {
110 case CONSUMER_TYPE_MOTION:
113 case CONSUMER_TYPE_ORIENTATION:
114 stop_orientation_.Wait();
116 case CONSUMER_TYPE_LIGHT:
122 void WaitForUpdate(ConsumerType consumer_type) {
123 switch (consumer_type) {
124 case CONSUMER_TYPE_MOTION:
125 updated_motion_.Wait();
127 case CONSUMER_TYPE_ORIENTATION:
128 updated_orientation_.Wait();
130 case CONSUMER_TYPE_LIGHT:
131 updated_light_.Wait();
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_;
148 DeviceLightHardwareBuffer* light_buffer_;
149 DeviceMotionHardwareBuffer* motion_buffer_;
150 DeviceOrientationHardwareBuffer* orientation_buffer_;
152 DISALLOW_COPY_AND_ASSIGN(FakeDataFetcher);
155 class FakeNonPollingDataFetcher : public FakeDataFetcher {
157 FakeNonPollingDataFetcher() { }
158 ~FakeNonPollingDataFetcher() override {}
160 bool Start(ConsumerType consumer_type, void* buffer) override {
161 Init(consumer_type, buffer);
162 switch (consumer_type) {
163 case CONSUMER_TYPE_MOTION:
165 start_motion_.Signal();
167 case CONSUMER_TYPE_ORIENTATION:
169 start_orientation_.Signal();
171 case CONSUMER_TYPE_LIGHT:
173 start_light_.Signal();
181 bool Stop(ConsumerType consumer_type) override {
182 switch (consumer_type) {
183 case CONSUMER_TYPE_MOTION:
184 stop_motion_.Signal();
186 case CONSUMER_TYPE_ORIENTATION:
187 stop_orientation_.Signal();
189 case CONSUMER_TYPE_LIGHT:
190 stop_light_.Signal();
198 void Fetch(unsigned consumer_bitmask) override {
199 FAIL() << "fetch should not be called, "
200 << "because this is a non-polling fetcher";
203 FetcherType GetType() const override { return FakeDataFetcher::GetType(); }
206 DISALLOW_COPY_AND_ASSIGN(FakeNonPollingDataFetcher);
209 class FakePollingDataFetcher : public FakeDataFetcher {
211 FakePollingDataFetcher() { }
212 ~FakePollingDataFetcher() override {}
214 bool Start(ConsumerType consumer_type, void* buffer) override {
215 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
217 Init(consumer_type, buffer);
218 switch (consumer_type) {
219 case CONSUMER_TYPE_MOTION:
220 start_motion_.Signal();
222 case CONSUMER_TYPE_ORIENTATION:
223 start_orientation_.Signal();
225 case CONSUMER_TYPE_LIGHT:
226 start_light_.Signal();
234 bool Stop(ConsumerType consumer_type) override {
235 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
237 switch (consumer_type) {
238 case CONSUMER_TYPE_MOTION:
239 stop_motion_.Signal();
241 case CONSUMER_TYPE_ORIENTATION:
242 stop_orientation_.Signal();
244 case CONSUMER_TYPE_LIGHT:
245 stop_light_.Signal();
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);
259 if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION)
261 if (consumer_bitmask & CONSUMER_TYPE_MOTION)
263 if (consumer_bitmask & CONSUMER_TYPE_LIGHT)
267 FetcherType GetType() const override { return FETCHER_TYPE_POLLING_CALLBACK; }
270 DISALLOW_COPY_AND_ASSIGN(FakePollingDataFetcher);
273 class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
275 FakeZeroDelayPollingDataFetcher() { }
276 ~FakeZeroDelayPollingDataFetcher() override {}
278 bool Start(ConsumerType consumer_type, void* buffer) override {
279 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
281 Init(consumer_type, buffer);
282 switch (consumer_type) {
283 case CONSUMER_TYPE_MOTION:
284 start_motion_.Signal();
286 case CONSUMER_TYPE_ORIENTATION:
287 start_orientation_.Signal();
289 case CONSUMER_TYPE_LIGHT:
290 start_light_.Signal();
298 bool Stop(ConsumerType consumer_type) override {
299 EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
301 switch (consumer_type) {
302 case CONSUMER_TYPE_MOTION:
303 stop_motion_.Signal();
305 case CONSUMER_TYPE_ORIENTATION:
306 stop_orientation_.Signal();
308 case CONSUMER_TYPE_LIGHT:
309 stop_light_.Signal();
317 void Fetch(unsigned consumer_bitmask) override {
318 FAIL() << "fetch should not be called";
321 FetcherType GetType() const override { return FETCHER_TYPE_SEPARATE_THREAD; }
323 bool IsPollingTimerRunningForTesting() const {
324 return FakeDataFetcher::IsPollingTimerRunningForTesting();
328 DISALLOW_COPY_AND_ASSIGN(FakeZeroDelayPollingDataFetcher);
332 TEST(DataFetcherSharedMemoryBaseTest, DoesStartMotion) {
333 FakeNonPollingDataFetcher fake_data_fetcher;
334 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
335 fake_data_fetcher.GetType());
337 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION));
338 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION);
340 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000.,
341 fake_data_fetcher.GetMotionBuffer()->data.interval);
343 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
344 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION);
347 TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) {
348 FakeNonPollingDataFetcher fake_data_fetcher;
349 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
350 fake_data_fetcher.GetType());
352 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
353 CONSUMER_TYPE_ORIENTATION));
354 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
356 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
358 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
359 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
362 TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) {
363 FakeNonPollingDataFetcher fake_data_fetcher;
364 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
365 fake_data_fetcher.GetType());
367 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT));
368 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT);
370 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
372 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
373 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
376 TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) {
377 FakePollingDataFetcher fake_data_fetcher;
378 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
379 fake_data_fetcher.GetType());
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);
385 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000.,
386 fake_data_fetcher.GetMotionBuffer()->data.interval);
388 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
389 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION);
392 TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) {
393 FakePollingDataFetcher fake_data_fetcher;
394 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
395 fake_data_fetcher.GetType());
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);
402 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
404 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
405 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
408 TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) {
409 FakePollingDataFetcher fake_data_fetcher;
410 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
411 fake_data_fetcher.GetType());
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);
417 EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
419 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
420 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
423 TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) {
424 FakePollingDataFetcher fake_data_fetcher;
425 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
426 fake_data_fetcher.GetType());
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));
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));
442 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
443 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION);
445 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION);
446 fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION);
448 EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
449 EXPECT_EQ(kInertialSensorIntervalMicroseconds / 1000.,
450 fake_data_fetcher.GetMotionBuffer()->data.interval);
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);
458 TEST(DataFetcherSharedMemoryBaseTest, DoesNotPollZeroDelay) {
459 FakeZeroDelayPollingDataFetcher fake_data_fetcher;
460 EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_SEPARATE_THREAD,
461 fake_data_fetcher.GetType());
463 EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
464 CONSUMER_TYPE_ORIENTATION));
465 fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
467 EXPECT_FALSE(fake_data_fetcher.IsPollingTimerRunningForTesting());
468 EXPECT_EQ(0, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
470 fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
471 fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
477 } // namespace content