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
16namespace content {
17
18namespace {
19
20class 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_(NULL),
33        motion_buffer_(NULL),
34        orientation_buffer_(NULL) {}
35  virtual ~FakeDataFetcher() { }
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 = kInertialSensorIntervalMillis;
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
155class FakeNonPollingDataFetcher : public FakeDataFetcher {
156 public:
157  FakeNonPollingDataFetcher() { }
158  virtual ~FakeNonPollingDataFetcher() { }
159
160  virtual 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  virtual 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  virtual void Fetch(unsigned consumer_bitmask) OVERRIDE {
199    FAIL() << "fetch should not be called, "
200        << "because this is a non-polling fetcher";
201  }
202
203  virtual FetcherType GetType() const OVERRIDE {
204    return FakeDataFetcher::GetType();
205  }
206
207 private:
208  DISALLOW_COPY_AND_ASSIGN(FakeNonPollingDataFetcher);
209};
210
211class FakePollingDataFetcher : public FakeDataFetcher {
212 public:
213  FakePollingDataFetcher() { }
214  virtual ~FakePollingDataFetcher() { }
215
216  virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE {
217    EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
218
219    Init(consumer_type, buffer);
220    switch (consumer_type) {
221      case CONSUMER_TYPE_MOTION:
222        start_motion_.Signal();
223        break;
224      case CONSUMER_TYPE_ORIENTATION:
225        start_orientation_.Signal();
226        break;
227      case CONSUMER_TYPE_LIGHT:
228        start_light_.Signal();
229        break;
230      default:
231        return false;
232    }
233    return true;
234  }
235
236  virtual bool Stop(ConsumerType consumer_type) OVERRIDE {
237    EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
238
239    switch (consumer_type) {
240      case CONSUMER_TYPE_MOTION:
241        stop_motion_.Signal();
242        break;
243      case CONSUMER_TYPE_ORIENTATION:
244        stop_orientation_.Signal();
245        break;
246      case CONSUMER_TYPE_LIGHT:
247        stop_light_.Signal();
248        break;
249      default:
250        return false;
251    }
252    return true;
253  }
254
255  virtual void Fetch(unsigned consumer_bitmask) OVERRIDE {
256    EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
257    EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION ||
258                consumer_bitmask & CONSUMER_TYPE_MOTION ||
259                consumer_bitmask & CONSUMER_TYPE_LIGHT);
260
261    if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION)
262      UpdateOrientation();
263    if (consumer_bitmask & CONSUMER_TYPE_MOTION)
264      UpdateMotion();
265    if (consumer_bitmask & CONSUMER_TYPE_LIGHT)
266      UpdateLight();
267  }
268
269  virtual FetcherType GetType() const OVERRIDE {
270    return FETCHER_TYPE_POLLING_CALLBACK;
271  }
272
273 private:
274  DISALLOW_COPY_AND_ASSIGN(FakePollingDataFetcher);
275};
276
277class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
278 public:
279  FakeZeroDelayPollingDataFetcher() { }
280  virtual ~FakeZeroDelayPollingDataFetcher() { }
281
282  virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE {
283    EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
284
285    Init(consumer_type, buffer);
286    switch (consumer_type) {
287      case CONSUMER_TYPE_MOTION:
288        start_motion_.Signal();
289        break;
290      case CONSUMER_TYPE_ORIENTATION:
291        start_orientation_.Signal();
292        break;
293      case CONSUMER_TYPE_LIGHT:
294        start_light_.Signal();
295        break;
296      default:
297        return false;
298    }
299    return true;
300  }
301
302  virtual bool Stop(ConsumerType consumer_type) OVERRIDE {
303    EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
304
305    switch (consumer_type) {
306      case CONSUMER_TYPE_MOTION:
307        stop_motion_.Signal();
308        break;
309      case CONSUMER_TYPE_ORIENTATION:
310        stop_orientation_.Signal();
311        break;
312      case CONSUMER_TYPE_LIGHT:
313        stop_light_.Signal();
314        break;
315      default:
316        return false;
317    }
318    return true;
319  }
320
321  virtual void Fetch(unsigned consumer_bitmask) OVERRIDE {
322    FAIL() << "fetch should not be called";
323  }
324
325  virtual FetcherType GetType() const OVERRIDE {
326    return FETCHER_TYPE_SEPARATE_THREAD;
327  }
328
329  bool IsPollingTimerRunningForTesting() const {
330    return FakeDataFetcher::IsPollingTimerRunningForTesting();
331  }
332
333 private:
334  DISALLOW_COPY_AND_ASSIGN(FakeZeroDelayPollingDataFetcher);
335};
336
337
338TEST(DataFetcherSharedMemoryBaseTest, DoesStartMotion) {
339  FakeNonPollingDataFetcher fake_data_fetcher;
340  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
341      fake_data_fetcher.GetType());
342
343  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION));
344  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION);
345
346  EXPECT_EQ(kInertialSensorIntervalMillis,
347      fake_data_fetcher.GetMotionBuffer()->data.interval);
348
349  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
350  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION);
351}
352
353TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) {
354  FakeNonPollingDataFetcher fake_data_fetcher;
355  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
356      fake_data_fetcher.GetType());
357
358  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
359      CONSUMER_TYPE_ORIENTATION));
360  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
361
362  EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
363
364  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
365  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
366}
367
368TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) {
369  FakeNonPollingDataFetcher fake_data_fetcher;
370  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
371            fake_data_fetcher.GetType());
372
373  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT));
374  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT);
375
376  EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
377
378  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
379  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
380}
381
382TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) {
383  FakePollingDataFetcher fake_data_fetcher;
384  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
385      fake_data_fetcher.GetType());
386
387  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_MOTION));
388  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION);
389  fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION);
390
391  EXPECT_EQ(kInertialSensorIntervalMillis,
392      fake_data_fetcher.GetMotionBuffer()->data.interval);
393
394  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
395  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION);
396}
397
398TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) {
399  FakePollingDataFetcher fake_data_fetcher;
400  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
401      fake_data_fetcher.GetType());
402
403  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
404      CONSUMER_TYPE_ORIENTATION));
405  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
406  fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION);
407
408  EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
409
410  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
411  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
412}
413
414TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) {
415  FakePollingDataFetcher fake_data_fetcher;
416  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
417            fake_data_fetcher.GetType());
418
419  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT));
420  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT);
421  fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_LIGHT);
422
423  EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
424
425  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
426  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
427}
428
429TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) {
430  FakePollingDataFetcher fake_data_fetcher;
431  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
432      fake_data_fetcher.GetType());
433
434  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
435      CONSUMER_TYPE_ORIENTATION));
436  base::SharedMemoryHandle handle_orientation =
437      fake_data_fetcher.GetSharedMemoryHandleForProcess(
438          CONSUMER_TYPE_ORIENTATION, base::GetCurrentProcessHandle());
439  EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_orientation));
440
441  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
442      CONSUMER_TYPE_MOTION));
443  base::SharedMemoryHandle handle_motion =
444      fake_data_fetcher.GetSharedMemoryHandleForProcess(
445          CONSUMER_TYPE_MOTION, base::GetCurrentProcessHandle());
446  EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle_motion));
447
448  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
449  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_MOTION);
450
451  fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_ORIENTATION);
452  fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_MOTION);
453
454  EXPECT_EQ(1, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
455  EXPECT_EQ(kInertialSensorIntervalMillis,
456      fake_data_fetcher.GetMotionBuffer()->data.interval);
457
458  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
459  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
460  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
461  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_MOTION);
462}
463
464TEST(DataFetcherSharedMemoryBaseTest, DoesNotPollZeroDelay) {
465  FakeZeroDelayPollingDataFetcher fake_data_fetcher;
466  EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_SEPARATE_THREAD,
467      fake_data_fetcher.GetType());
468
469  EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(
470      CONSUMER_TYPE_ORIENTATION));
471  fake_data_fetcher.WaitForStart(CONSUMER_TYPE_ORIENTATION);
472
473  EXPECT_FALSE(fake_data_fetcher.IsPollingTimerRunningForTesting());
474  EXPECT_EQ(0, fake_data_fetcher.GetOrientationBuffer()->data.alpha);
475
476  fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
477  fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
478}
479
480
481}  // namespace
482
483}  // namespace content
484