Home | History | Annotate | Download | only in device_sensors
      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 "device_orientation_event_pump.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
     10 #include "content/public/test/test_utils.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "third_party/WebKit/public/platform/WebDeviceOrientationListener.h"
     13 
     14 namespace content {
     15 
     16 class MockDeviceOrientationListener
     17     : public blink::WebDeviceOrientationListener {
     18  public:
     19   MockDeviceOrientationListener() : did_change_device_orientation_(false) {
     20     memset(&data_, 0, sizeof(data_));
     21   }
     22   virtual ~MockDeviceOrientationListener() { }
     23 
     24   virtual void didChangeDeviceOrientation(
     25       const blink::WebDeviceOrientationData& data) OVERRIDE {
     26     memcpy(&data_, &data, sizeof(data));
     27     did_change_device_orientation_ = true;
     28   }
     29 
     30   bool did_change_device_orientation() const {
     31     return did_change_device_orientation_;
     32   }
     33   void set_did_change_device_orientation(bool value) {
     34     did_change_device_orientation_ = value;
     35   }
     36   const blink::WebDeviceOrientationData& data() const {
     37     return data_;
     38   }
     39 
     40  private:
     41   bool did_change_device_orientation_;
     42   blink::WebDeviceOrientationData data_;
     43 
     44   DISALLOW_COPY_AND_ASSIGN(MockDeviceOrientationListener);
     45 };
     46 
     47 class DeviceOrientationEventPumpForTesting : public DeviceOrientationEventPump {
     48  public:
     49   DeviceOrientationEventPumpForTesting()
     50       : DeviceOrientationEventPump(0) { }
     51   virtual ~DeviceOrientationEventPumpForTesting() { }
     52 
     53   void OnDidStart(base::SharedMemoryHandle renderer_handle) {
     54     DeviceOrientationEventPump::OnDidStart(renderer_handle);
     55   }
     56   virtual void SendStartMessage() OVERRIDE { }
     57   virtual void SendStopMessage() OVERRIDE { }
     58   virtual void FireEvent() OVERRIDE {
     59     DeviceOrientationEventPump::FireEvent();
     60     Stop();
     61     base::MessageLoop::current()->QuitWhenIdle();
     62   }
     63 
     64  private:
     65   DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpForTesting);
     66 };
     67 
     68 class DeviceOrientationEventPumpTest : public testing::Test {
     69  public:
     70   DeviceOrientationEventPumpTest() {
     71       EXPECT_TRUE(shared_memory_.CreateAndMapAnonymous(
     72           sizeof(DeviceOrientationHardwareBuffer)));
     73   }
     74 
     75  protected:
     76   virtual void SetUp() OVERRIDE {
     77     const DeviceOrientationHardwareBuffer* null_buffer = NULL;
     78     listener_.reset(new MockDeviceOrientationListener);
     79     orientation_pump_.reset(new DeviceOrientationEventPumpForTesting);
     80     buffer_ = static_cast<DeviceOrientationHardwareBuffer*>(
     81         shared_memory_.memory());
     82     ASSERT_NE(null_buffer, buffer_);
     83     memset(buffer_, 0, sizeof(DeviceOrientationHardwareBuffer));
     84     ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(),
     85         &handle_));
     86   }
     87 
     88   void InitBuffer() {
     89     blink::WebDeviceOrientationData& data = buffer_->data;
     90     data.alpha = 1;
     91     data.hasAlpha = true;
     92     data.beta = 2;
     93     data.hasBeta = true;
     94     data.gamma = 3;
     95     data.hasGamma = true;
     96     data.allAvailableSensorsAreActive = true;
     97   }
     98 
     99   void InitBufferNoData() {
    100     blink::WebDeviceOrientationData& data = buffer_->data;
    101     data.allAvailableSensorsAreActive = true;
    102   }
    103 
    104   MockDeviceOrientationListener* listener() { return listener_.get(); }
    105   DeviceOrientationEventPumpForTesting* orientation_pump() {
    106     return orientation_pump_.get();
    107   }
    108   base::SharedMemoryHandle handle() { return handle_; }
    109   DeviceOrientationHardwareBuffer* buffer() { return buffer_; }
    110 
    111  private:
    112   scoped_ptr<MockDeviceOrientationListener> listener_;
    113   scoped_ptr<DeviceOrientationEventPumpForTesting> orientation_pump_;
    114   base::SharedMemoryHandle handle_;
    115   base::SharedMemory shared_memory_;
    116   DeviceOrientationHardwareBuffer* buffer_;
    117 
    118   DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest);
    119 };
    120 
    121 TEST_F(DeviceOrientationEventPumpTest, DidStartPolling) {
    122   base::MessageLoop loop;
    123 
    124   InitBuffer();
    125   orientation_pump()->Start(listener());
    126   orientation_pump()->OnDidStart(handle());
    127 
    128   base::MessageLoop::current()->Run();
    129 
    130   const blink::WebDeviceOrientationData& received_data = listener()->data();
    131   EXPECT_TRUE(listener()->did_change_device_orientation());
    132   EXPECT_TRUE(received_data.allAvailableSensorsAreActive);
    133   EXPECT_EQ(1, static_cast<double>(received_data.alpha));
    134   EXPECT_TRUE(received_data.hasAlpha);
    135   EXPECT_EQ(2, static_cast<double>(received_data.beta));
    136   EXPECT_TRUE(received_data.hasBeta);
    137   EXPECT_EQ(3, static_cast<double>(received_data.gamma));
    138   EXPECT_TRUE(received_data.hasGamma);
    139 }
    140 
    141 TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
    142   base::MessageLoop loop;
    143 
    144   InitBufferNoData();
    145   orientation_pump()->Start(listener());
    146   orientation_pump()->OnDidStart(handle());
    147 
    148   base::MessageLoop::current()->Run();
    149 
    150   const blink::WebDeviceOrientationData& received_data = listener()->data();
    151   EXPECT_TRUE(listener()->did_change_device_orientation());
    152   EXPECT_TRUE(received_data.allAvailableSensorsAreActive);
    153   EXPECT_FALSE(received_data.hasAlpha);
    154   EXPECT_FALSE(received_data.hasBeta);
    155   EXPECT_FALSE(received_data.hasGamma);
    156 }
    157 
    158 TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
    159   base::MessageLoop loop;
    160 
    161   InitBuffer();
    162   orientation_pump()->Start(listener());
    163   orientation_pump()->OnDidStart(handle());
    164 
    165   base::MessageLoop::current()->Run();
    166 
    167   const blink::WebDeviceOrientationData& received_data = listener()->data();
    168   EXPECT_TRUE(listener()->did_change_device_orientation());
    169   EXPECT_TRUE(received_data.allAvailableSensorsAreActive);
    170   EXPECT_EQ(1, static_cast<double>(received_data.alpha));
    171   EXPECT_TRUE(received_data.hasAlpha);
    172   EXPECT_EQ(2, static_cast<double>(received_data.beta));
    173   EXPECT_TRUE(received_data.hasBeta);
    174   EXPECT_EQ(3, static_cast<double>(received_data.gamma));
    175   EXPECT_TRUE(received_data.hasGamma);
    176 
    177   buffer()->data.alpha =
    178       1 + DeviceOrientationEventPump::kOrientationThreshold / 2.0;
    179   listener()->set_did_change_device_orientation(false);
    180 
    181   // Reset the pump's listener.
    182   orientation_pump()->Start(listener());
    183 
    184   base::MessageLoop::current()->PostTask(FROM_HERE,
    185       base::Bind(&DeviceOrientationEventPumpForTesting::FireEvent,
    186                  base::Unretained(orientation_pump())));
    187   base::MessageLoop::current()->Run();
    188 
    189   EXPECT_FALSE(listener()->did_change_device_orientation());
    190   EXPECT_TRUE(received_data.allAvailableSensorsAreActive);
    191   EXPECT_EQ(1, static_cast<double>(received_data.alpha));
    192   EXPECT_TRUE(received_data.hasAlpha);
    193   EXPECT_EQ(2, static_cast<double>(received_data.beta));
    194   EXPECT_TRUE(received_data.hasBeta);
    195   EXPECT_EQ(3, static_cast<double>(received_data.gamma));
    196   EXPECT_TRUE(received_data.hasGamma);
    197 
    198   buffer()->data.alpha =
    199       1 + DeviceOrientationEventPump::kOrientationThreshold;
    200   listener()->set_did_change_device_orientation(false);
    201 
    202   // Reset the pump's listener.
    203   orientation_pump()->Start(listener());
    204 
    205   base::MessageLoop::current()->PostTask(FROM_HERE,
    206       base::Bind(&DeviceOrientationEventPumpForTesting::FireEvent,
    207                  base::Unretained(orientation_pump())));
    208   base::MessageLoop::current()->Run();
    209 
    210   EXPECT_TRUE(listener()->did_change_device_orientation());
    211   EXPECT_EQ(1 + DeviceOrientationEventPump::kOrientationThreshold,
    212       static_cast<double>(received_data.alpha));
    213 }
    214 
    215 }  // namespace content
    216