Commit f07da397 authored by rijubrata.bhaumik's avatar rijubrata.bhaumik Committed by Commit bot

[DeviceLight] Browser+java part

This is part 2 of the Adding Device Light [content side]
Adding the Browser and Java part in the content side for the
DeviceLight API.

BUG=336424

Review URL: https://codereview.chromium.org/292693004

Cr-Commit-Position: refs/heads/master@{#295937}
parent d6a52053
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "content/browser/device_sensors/data_fetcher_shared_memory_base.h" #include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
#endif #endif
...@@ -35,6 +36,7 @@ class CONTENT_EXPORT DataFetcherSharedMemory ...@@ -35,6 +36,7 @@ class CONTENT_EXPORT DataFetcherSharedMemory
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
DeviceMotionHardwareBuffer* motion_buffer_; DeviceMotionHardwareBuffer* motion_buffer_;
DeviceOrientationHardwareBuffer* orientation_buffer_; DeviceOrientationHardwareBuffer* orientation_buffer_;
DeviceLightHardwareBuffer* light_buffer_;
#endif #endif
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
virtual void Fetch(unsigned consumer_bitmask) OVERRIDE; virtual void Fetch(unsigned consumer_bitmask) OVERRIDE;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "content/browser/device_sensors/sensor_manager_android.h" #include "content/browser/device_sensors/sensor_manager_android.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
...@@ -29,6 +30,9 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) { ...@@ -29,6 +30,9 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
return SensorManagerAndroid::GetInstance()-> return SensorManagerAndroid::GetInstance()->
StartFetchingDeviceOrientationData( StartFetchingDeviceOrientationData(
static_cast<DeviceOrientationHardwareBuffer*>(buffer)); static_cast<DeviceOrientationHardwareBuffer*>(buffer));
case CONSUMER_TYPE_LIGHT:
return SensorManagerAndroid::GetInstance()->StartFetchingDeviceLightData(
static_cast<DeviceLightHardwareBuffer*>(buffer));
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -43,6 +47,9 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { ...@@ -43,6 +47,9 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
SensorManagerAndroid::GetInstance()->StopFetchingDeviceOrientationData(); SensorManagerAndroid::GetInstance()->StopFetchingDeviceOrientationData();
return true; return true;
case CONSUMER_TYPE_LIGHT:
SensorManagerAndroid::GetInstance()->StopFetchingDeviceLightData();
return true;
default: default:
NOTREACHED(); NOTREACHED();
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
...@@ -22,6 +23,8 @@ static size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) { ...@@ -22,6 +23,8 @@ static size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) {
return sizeof(DeviceMotionHardwareBuffer); return sizeof(DeviceMotionHardwareBuffer);
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
return sizeof(DeviceOrientationHardwareBuffer); return sizeof(DeviceOrientationHardwareBuffer);
case CONSUMER_TYPE_LIGHT:
return sizeof(DeviceLightHardwareBuffer);
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -165,6 +168,7 @@ bool DataFetcherSharedMemoryBase::StopFetchingDeviceData( ...@@ -165,6 +168,7 @@ bool DataFetcherSharedMemoryBase::StopFetchingDeviceData(
void DataFetcherSharedMemoryBase::StopFetchingAllDeviceData() { void DataFetcherSharedMemoryBase::StopFetchingAllDeviceData() {
StopFetchingDeviceData(CONSUMER_TYPE_MOTION); StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION); StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
} }
base::SharedMemoryHandle base::SharedMemoryHandle
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/process/process_handle.h" #include "base/process/process_handle.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -19,15 +20,18 @@ namespace { ...@@ -19,15 +20,18 @@ namespace {
class FakeDataFetcher : public DataFetcherSharedMemoryBase { class FakeDataFetcher : public DataFetcherSharedMemoryBase {
public: public:
FakeDataFetcher() FakeDataFetcher()
: start_motion_(false, false), : start_light_(false, false),
start_motion_(false, false),
start_orientation_(false, false), start_orientation_(false, false),
stop_light_(false, false),
stop_motion_(false, false), stop_motion_(false, false),
stop_orientation_(false, false), stop_orientation_(false, false),
updated_light_(false, false),
updated_motion_(false, false), updated_motion_(false, false),
updated_orientation_(false, false), updated_orientation_(false, false),
light_buffer_(NULL),
motion_buffer_(NULL), motion_buffer_(NULL),
orientation_buffer_(NULL) { orientation_buffer_(NULL) {}
}
virtual ~FakeDataFetcher() { } virtual ~FakeDataFetcher() { }
bool Init(ConsumerType consumer_type, void* buffer) { bool Init(ConsumerType consumer_type, void* buffer) {
...@@ -41,12 +45,24 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase { ...@@ -41,12 +45,24 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
orientation_buffer_ = orientation_buffer_ =
static_cast<DeviceOrientationHardwareBuffer*>(buffer); static_cast<DeviceOrientationHardwareBuffer*>(buffer);
break; break;
case CONSUMER_TYPE_LIGHT:
light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer);
break;
default: default:
return false; return false;
} }
return true; return true;
} }
void UpdateLight() {
DeviceLightHardwareBuffer* buffer = GetLightBuffer();
ASSERT_TRUE(buffer);
buffer->seqlock.WriteBegin();
buffer->data.value = 100;
buffer->seqlock.WriteEnd();
updated_light_.Signal();
}
void UpdateMotion() { void UpdateMotion() {
DeviceMotionHardwareBuffer* buffer = GetMotionBuffer(); DeviceMotionHardwareBuffer* buffer = GetMotionBuffer();
ASSERT_TRUE(buffer); ASSERT_TRUE(buffer);
...@@ -65,6 +81,8 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase { ...@@ -65,6 +81,8 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
updated_orientation_.Signal(); updated_orientation_.Signal();
} }
DeviceLightHardwareBuffer* GetLightBuffer() const { return light_buffer_; }
DeviceMotionHardwareBuffer* GetMotionBuffer() const { DeviceMotionHardwareBuffer* GetMotionBuffer() const {
return motion_buffer_; return motion_buffer_;
} }
...@@ -81,6 +99,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase { ...@@ -81,6 +99,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Wait(); start_orientation_.Wait();
break; break;
case CONSUMER_TYPE_LIGHT:
start_light_.Wait();
break;
} }
} }
...@@ -92,6 +113,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase { ...@@ -92,6 +113,9 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Wait(); stop_orientation_.Wait();
break; break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Wait();
break;
} }
} }
...@@ -103,18 +127,25 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase { ...@@ -103,18 +127,25 @@ class FakeDataFetcher : public DataFetcherSharedMemoryBase {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
updated_orientation_.Wait(); updated_orientation_.Wait();
break; break;
case CONSUMER_TYPE_LIGHT:
updated_light_.Wait();
break;
} }
} }
protected: protected:
base::WaitableEvent start_light_;
base::WaitableEvent start_motion_; base::WaitableEvent start_motion_;
base::WaitableEvent start_orientation_; base::WaitableEvent start_orientation_;
base::WaitableEvent stop_light_;
base::WaitableEvent stop_motion_; base::WaitableEvent stop_motion_;
base::WaitableEvent stop_orientation_; base::WaitableEvent stop_orientation_;
base::WaitableEvent updated_light_;
base::WaitableEvent updated_motion_; base::WaitableEvent updated_motion_;
base::WaitableEvent updated_orientation_; base::WaitableEvent updated_orientation_;
private: private:
DeviceLightHardwareBuffer* light_buffer_;
DeviceMotionHardwareBuffer* motion_buffer_; DeviceMotionHardwareBuffer* motion_buffer_;
DeviceOrientationHardwareBuffer* orientation_buffer_; DeviceOrientationHardwareBuffer* orientation_buffer_;
...@@ -137,6 +168,10 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher { ...@@ -137,6 +168,10 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher {
UpdateOrientation(); UpdateOrientation();
start_orientation_.Signal(); start_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
UpdateLight();
start_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -151,6 +186,9 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher { ...@@ -151,6 +186,9 @@ class FakeNonPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal(); stop_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -186,6 +224,9 @@ class FakePollingDataFetcher : public FakeDataFetcher { ...@@ -186,6 +224,9 @@ class FakePollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Signal(); start_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
start_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -202,6 +243,9 @@ class FakePollingDataFetcher : public FakeDataFetcher { ...@@ -202,6 +243,9 @@ class FakePollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal(); stop_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -211,12 +255,15 @@ class FakePollingDataFetcher : public FakeDataFetcher { ...@@ -211,12 +255,15 @@ class FakePollingDataFetcher : public FakeDataFetcher {
virtual void Fetch(unsigned consumer_bitmask) OVERRIDE { virtual void Fetch(unsigned consumer_bitmask) OVERRIDE {
EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop()); EXPECT_TRUE(base::MessageLoop::current() == GetPollingMessageLoop());
EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION || EXPECT_TRUE(consumer_bitmask & CONSUMER_TYPE_ORIENTATION ||
consumer_bitmask & CONSUMER_TYPE_MOTION); consumer_bitmask & CONSUMER_TYPE_MOTION ||
consumer_bitmask & CONSUMER_TYPE_LIGHT);
if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION) if (consumer_bitmask & CONSUMER_TYPE_ORIENTATION)
UpdateOrientation(); UpdateOrientation();
if (consumer_bitmask & CONSUMER_TYPE_MOTION) if (consumer_bitmask & CONSUMER_TYPE_MOTION)
UpdateMotion(); UpdateMotion();
if (consumer_bitmask & CONSUMER_TYPE_LIGHT)
UpdateLight();
} }
virtual FetcherType GetType() const OVERRIDE { virtual FetcherType GetType() const OVERRIDE {
...@@ -243,6 +290,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher { ...@@ -243,6 +290,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
start_orientation_.Signal(); start_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
start_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -259,6 +309,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher { ...@@ -259,6 +309,9 @@ class FakeZeroDelayPollingDataFetcher : public FakeDataFetcher {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
stop_orientation_.Signal(); stop_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
stop_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -312,6 +365,20 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) { ...@@ -312,6 +365,20 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesStartOrientation) {
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
} }
TEST(DataFetcherSharedMemoryBaseTest, DoesStartLight) {
FakeNonPollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_DEFAULT,
fake_data_fetcher.GetType());
EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT));
fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT);
EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
}
TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) { TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotion) {
FakePollingDataFetcher fake_data_fetcher; FakePollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
...@@ -344,6 +411,21 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) { ...@@ -344,6 +411,21 @@ TEST(DataFetcherSharedMemoryBaseTest, DoesPollOrientation) {
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION); fake_data_fetcher.WaitForStop(CONSUMER_TYPE_ORIENTATION);
} }
TEST(DataFetcherSharedMemoryBaseTest, DoesPollLight) {
FakePollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
fake_data_fetcher.GetType());
EXPECT_TRUE(fake_data_fetcher.StartFetchingDeviceData(CONSUMER_TYPE_LIGHT));
fake_data_fetcher.WaitForStart(CONSUMER_TYPE_LIGHT);
fake_data_fetcher.WaitForUpdate(CONSUMER_TYPE_LIGHT);
EXPECT_EQ(100, fake_data_fetcher.GetLightBuffer()->data.value);
fake_data_fetcher.StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
fake_data_fetcher.WaitForStop(CONSUMER_TYPE_LIGHT);
}
TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) { TEST(DataFetcherSharedMemoryBaseTest, DoesPollMotionAndOrientation) {
FakePollingDataFetcher fake_data_fetcher; FakePollingDataFetcher fake_data_fetcher;
EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK, EXPECT_EQ(DataFetcherSharedMemoryBase::FETCHER_TYPE_POLLING_CALLBACK,
......
...@@ -29,12 +29,22 @@ static bool SetOrientationBuffer( ...@@ -29,12 +29,22 @@ static bool SetOrientationBuffer(
return true; return true;
} }
static bool SetLightBuffer(content::DeviceLightHardwareBuffer* buffer,
double lux) {
if (!buffer)
return false;
buffer->seqlock.WriteBegin();
buffer->data.value = lux;
buffer->seqlock.WriteEnd();
return true;
}
} // namespace } // namespace
namespace content { namespace content {
DataFetcherSharedMemory::DataFetcherSharedMemory() DataFetcherSharedMemory::DataFetcherSharedMemory()
: motion_buffer_(NULL), orientation_buffer_(NULL) { : motion_buffer_(NULL), orientation_buffer_(NULL), light_buffer_(NULL) {
} }
DataFetcherSharedMemory::~DataFetcherSharedMemory() { DataFetcherSharedMemory::~DataFetcherSharedMemory() {
...@@ -54,6 +64,10 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) { ...@@ -54,6 +64,10 @@ bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
UMA_HISTOGRAM_BOOLEAN("InertialSensor.OrientationDefaultAvailable", UMA_HISTOGRAM_BOOLEAN("InertialSensor.OrientationDefaultAvailable",
false); false);
return SetOrientationBuffer(orientation_buffer_, true); return SetOrientationBuffer(orientation_buffer_, true);
case CONSUMER_TYPE_LIGHT:
light_buffer_ = static_cast<DeviceLightHardwareBuffer*>(buffer);
return SetLightBuffer(light_buffer_,
std::numeric_limits<double>::infinity());
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -66,6 +80,8 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) { ...@@ -66,6 +80,8 @@ bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
return SetMotionBuffer(motion_buffer_, false); return SetMotionBuffer(motion_buffer_, false);
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
return SetOrientationBuffer(orientation_buffer_, false); return SetOrientationBuffer(orientation_buffer_, false);
case CONSUMER_TYPE_LIGHT:
return SetLightBuffer(light_buffer_, -1);
default: default:
NOTREACHED(); NOTREACHED();
} }
......
...@@ -2,14 +2,17 @@ ...@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/command_line.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "content/browser/device_sensors/data_fetcher_shared_memory.h" #include "content/browser/device_sensors/data_fetcher_shared_memory.h"
#include "content/browser/device_sensors/device_inertial_sensor_service.h" #include "content/browser/device_sensors/device_inertial_sensor_service.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h" #include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_navigation_observer.h"
...@@ -28,8 +31,9 @@ class FakeDataFetcher : public DataFetcherSharedMemory { ...@@ -28,8 +31,9 @@ class FakeDataFetcher : public DataFetcherSharedMemory {
stopped_orientation_(false, false), stopped_orientation_(false, false),
started_motion_(false, false), started_motion_(false, false),
stopped_motion_(false, false), stopped_motion_(false, false),
sensor_data_available_(true) { started_light_(false, false),
} stopped_light_(false, false),
sensor_data_available_(true) {}
virtual ~FakeDataFetcher() { } virtual ~FakeDataFetcher() { }
virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE { virtual bool Start(ConsumerType consumer_type, void* buffer) OVERRIDE {
...@@ -56,6 +60,17 @@ class FakeDataFetcher : public DataFetcherSharedMemory { ...@@ -56,6 +60,17 @@ class FakeDataFetcher : public DataFetcherSharedMemory {
started_orientation_.Signal(); started_orientation_.Signal();
} }
break; break;
case CONSUMER_TYPE_LIGHT:
{
DeviceLightHardwareBuffer* light_buffer =
static_cast<DeviceLightHardwareBuffer*>(buffer);
UpdateLight(light_buffer,
sensor_data_available_
? 100
: std::numeric_limits<double>::infinity());
started_light_.Signal();
}
break;
default: default:
return false; return false;
} }
...@@ -70,6 +85,9 @@ class FakeDataFetcher : public DataFetcherSharedMemory { ...@@ -70,6 +85,9 @@ class FakeDataFetcher : public DataFetcherSharedMemory {
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
stopped_orientation_.Signal(); stopped_orientation_.Signal();
break; break;
case CONSUMER_TYPE_LIGHT:
stopped_light_.Signal();
break;
default: default:
return false; return false;
} }
...@@ -140,10 +158,18 @@ class FakeDataFetcher : public DataFetcherSharedMemory { ...@@ -140,10 +158,18 @@ class FakeDataFetcher : public DataFetcherSharedMemory {
buffer->seqlock.WriteEnd(); buffer->seqlock.WriteEnd();
} }
void UpdateLight(DeviceLightHardwareBuffer* buffer, double lux) {
buffer->seqlock.WriteBegin();
buffer->data.value = lux;
buffer->seqlock.WriteEnd();
}
base::WaitableEvent started_orientation_; base::WaitableEvent started_orientation_;
base::WaitableEvent stopped_orientation_; base::WaitableEvent stopped_orientation_;
base::WaitableEvent started_motion_; base::WaitableEvent started_motion_;
base::WaitableEvent stopped_motion_; base::WaitableEvent stopped_motion_;
base::WaitableEvent started_light_;
base::WaitableEvent stopped_light_;
bool sensor_data_available_; bool sensor_data_available_;
private: private:
...@@ -195,13 +221,11 @@ class DeviceInertialSensorBrowserTest : public ContentBrowserTest { ...@@ -195,13 +221,11 @@ class DeviceInertialSensorBrowserTest : public ContentBrowserTest {
base::WaitableEvent io_loop_finished_event_; base::WaitableEvent io_loop_finished_event_;
}; };
IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, OrientationTest) { IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, OrientationTest) {
// The test page will register an event handler for orientation events, // The test page will register an event handler for orientation events,
// expects to get an event with fake values, then removes the event // expects to get an event with fake values, then removes the event
// handler and navigates to #pass. // handler and navigates to #pass.
GURL test_url = GetTestUrl( GURL test_url = GetTestUrl("device_sensors", "device_orientation_test.html");
"device_orientation", "device_orientation_test.html");
NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
...@@ -209,12 +233,31 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, OrientationTest) { ...@@ -209,12 +233,31 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, OrientationTest) {
fetcher_->stopped_orientation_.Wait(); fetcher_->stopped_orientation_.Wait();
} }
IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, LightTest) {
// The test page will register an event handler for light events,
// expects to get an event with fake values, then removes the event
// handler and navigates to #pass.
GURL test_url = GetTestUrl("device_sensors", "device_light_test.html");
// TODO(riju): remove command line args when the feature goes stable.
if (!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExperimentalWebPlatformFeatures)) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
}
NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
fetcher_->started_light_.Wait();
fetcher_->stopped_light_.Wait();
}
IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, MotionTest) { IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, MotionTest) {
// The test page will register an event handler for motion events, // The test page will register an event handler for motion events,
// expects to get an event with fake values, then removes the event // expects to get an event with fake values, then removes the event
// handler and navigates to #pass. // handler and navigates to #pass.
GURL test_url = GetTestUrl( GURL test_url = GetTestUrl("device_sensors", "device_motion_test.html");
"device_orientation", "device_motion_test.html");
NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2); NavigateToURLBlockUntilNavigationsComplete(shell(), test_url, 2);
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref()); EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
...@@ -222,6 +265,35 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, MotionTest) { ...@@ -222,6 +265,35 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, MotionTest) {
fetcher_->stopped_motion_.Wait(); fetcher_->stopped_motion_.Wait();
} }
IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest,
LightOneOffInfintyTest) {
// The test page will register an event handler for light events,
// expects to get an event with value equal to Infinity. This tests that the
// one-off infinity event still propagates to window after the alert is
// dismissed and the callback is invoked which navigates to #pass.
fetcher_->SetSensorDataAvailable(false);
// TODO(riju): remove command line args when the feature goes stable.
if (!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExperimentalWebPlatformFeatures)) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
}
TestNavigationObserver same_tab_observer(shell()->web_contents(), 2);
GURL test_url =
GetTestUrl("device_sensors", "device_light_infinity_test.html");
shell()->LoadURL(test_url);
WaitForAlertDialogAndQuitAfterDelay(base::TimeDelta::FromMilliseconds(1000));
fetcher_->started_light_.Wait();
fetcher_->stopped_light_.Wait();
same_tab_observer.Wait();
EXPECT_EQ("pass", shell()->web_contents()->GetLastCommittedURL().ref());
}
// Flaking in the android try bot. See http://crbug.com/360578. // Flaking in the android try bot. See http://crbug.com/360578.
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#define MAYBE_OrientationNullTestWithAlert DISABLED_OrientationNullTestWithAlert #define MAYBE_OrientationNullTestWithAlert DISABLED_OrientationNullTestWithAlert
...@@ -238,8 +310,8 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, ...@@ -238,8 +310,8 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest,
fetcher_->SetSensorDataAvailable(false); fetcher_->SetSensorDataAvailable(false);
TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); TestNavigationObserver same_tab_observer(shell()->web_contents(), 2);
GURL test_url = GetTestUrl( GURL test_url = GetTestUrl("device_sensors",
"device_orientation", "device_orientation_null_test_with_alert.html"); "device_orientation_null_test_with_alert.html");
shell()->LoadURL(test_url); shell()->LoadURL(test_url);
// TODO(timvolodine): investigate if it is possible to test this without // TODO(timvolodine): investigate if it is possible to test this without
...@@ -268,8 +340,8 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest, ...@@ -268,8 +340,8 @@ IN_PROC_BROWSER_TEST_F(DeviceInertialSensorBrowserTest,
fetcher_->SetSensorDataAvailable(false); fetcher_->SetSensorDataAvailable(false);
TestNavigationObserver same_tab_observer(shell()->web_contents(), 2); TestNavigationObserver same_tab_observer(shell()->web_contents(), 2);
GURL test_url = GetTestUrl( GURL test_url =
"device_orientation", "device_motion_null_test_with_alert.html"); GetTestUrl("device_sensors", "device_motion_null_test_with_alert.html");
shell()->LoadURL(test_url); shell()->LoadURL(test_url);
// TODO(timvolodine): investigate if it is possible to test this without // TODO(timvolodine): investigate if it is possible to test this without
......
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
namespace content { namespace content {
DeviceInertialSensorService::DeviceInertialSensorService() DeviceInertialSensorService::DeviceInertialSensorService()
: num_motion_readers_(0), : num_light_readers_(0),
num_motion_readers_(0),
num_orientation_readers_(0), num_orientation_readers_(0),
is_shutdown_(false) { is_shutdown_(false) {
} }
...@@ -59,6 +60,10 @@ bool DeviceInertialSensorService::ChangeNumberConsumers( ...@@ -59,6 +60,10 @@ bool DeviceInertialSensorService::ChangeNumberConsumers(
num_orientation_readers_ += delta; num_orientation_readers_ += delta;
DCHECK_GE(num_orientation_readers_ , 0); DCHECK_GE(num_orientation_readers_ , 0);
return true; return true;
case CONSUMER_TYPE_LIGHT:
num_light_readers_ += delta;
DCHECK_GE(num_light_readers_, 0);
return true;
default: default:
NOTREACHED(); NOTREACHED();
} }
...@@ -72,6 +77,8 @@ int DeviceInertialSensorService::GetNumberConsumers( ...@@ -72,6 +77,8 @@ int DeviceInertialSensorService::GetNumberConsumers(
return num_motion_readers_; return num_motion_readers_;
case CONSUMER_TYPE_ORIENTATION: case CONSUMER_TYPE_ORIENTATION:
return num_orientation_readers_; return num_orientation_readers_;
case CONSUMER_TYPE_LIGHT:
return num_light_readers_;
default: default:
NOTREACHED(); NOTREACHED();
} }
......
...@@ -57,6 +57,7 @@ class CONTENT_EXPORT DeviceInertialSensorService { ...@@ -57,6 +57,7 @@ class CONTENT_EXPORT DeviceInertialSensorService {
int delta); int delta);
int GetNumberConsumers(ConsumerType consumer_type) const; int GetNumberConsumers(ConsumerType consumer_type) const;
int num_light_readers_;
int num_motion_readers_; int num_motion_readers_;
int num_orientation_readers_; int num_orientation_readers_;
bool is_shutdown_; bool is_shutdown_;
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_sensors/device_light_message_filter.h"
#include "content/browser/device_sensors/device_inertial_sensor_service.h"
#include "content/common/device_sensors/device_light_messages.h"
namespace content {
DeviceLightMessageFilter::DeviceLightMessageFilter()
: BrowserMessageFilter(DeviceLightMsgStart), is_started_(false) {
}
DeviceLightMessageFilter::~DeviceLightMessageFilter() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (is_started_) {
DeviceInertialSensorService::GetInstance()->RemoveConsumer(
CONSUMER_TYPE_LIGHT);
}
}
bool DeviceLightMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(DeviceLightMessageFilter, message)
IPC_MESSAGE_HANDLER(DeviceLightHostMsg_StartPolling,
OnDeviceLightStartPolling)
IPC_MESSAGE_HANDLER(DeviceLightHostMsg_StopPolling, OnDeviceLightStopPolling)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void DeviceLightMessageFilter::OnDeviceLightStartPolling() {
DCHECK(!is_started_);
if (is_started_)
return;
is_started_ = true;
DeviceInertialSensorService::GetInstance()->AddConsumer(CONSUMER_TYPE_LIGHT);
DidStartDeviceLightPolling();
}
void DeviceLightMessageFilter::OnDeviceLightStopPolling() {
DCHECK(is_started_);
if (!is_started_)
return;
is_started_ = false;
DeviceInertialSensorService::GetInstance()->RemoveConsumer(
CONSUMER_TYPE_LIGHT);
}
void DeviceLightMessageFilter::DidStartDeviceLightPolling() {
Send(new DeviceLightMsg_DidStartPolling(
DeviceInertialSensorService::GetInstance()
->GetSharedMemoryHandleForProcess(CONSUMER_TYPE_LIGHT,
PeerHandle())));
}
} // namespace content
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_LIGHT_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_LIGHT_MESSAGE_FILTER_H_
#include "content/public/browser/browser_message_filter.h"
namespace content {
class DeviceLightMessageFilter : public BrowserMessageFilter {
public:
DeviceLightMessageFilter();
// BrowserMessageFilter implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
virtual ~DeviceLightMessageFilter();
void OnDeviceLightStartPolling();
void OnDeviceLightStopPolling();
void DidStartDeviceLightPolling();
bool is_started_;
DISALLOW_COPY_AND_ASSIGN(DeviceLightMessageFilter);
};
} // namespace content
#endif // CONTENT_BROWSER_DEVICE_SENSORS_DEVICE_LIGHT_MESSAGE_FILTER_H_
...@@ -7,18 +7,22 @@ ...@@ -7,18 +7,22 @@
namespace content { namespace content {
// Constants related to the Device Motion/Device Orientation APIs. // Constants related to the Device {Motion|Orientation|Light} APIs.
enum ConsumerType { enum ConsumerType {
CONSUMER_TYPE_MOTION = 1 << 0, CONSUMER_TYPE_MOTION = 1 << 0,
CONSUMER_TYPE_ORIENTATION = 1 << 1, CONSUMER_TYPE_ORIENTATION = 1 << 1,
CONSUMER_TYPE_LIGHT = 1 << 2,
}; };
// Specifies the minimal interval between subsequent sensor data updates. // Specifies the minimal interval between subsequent sensor data updates.
// Note that when changing this value it is desirable to have an adequate // Note that when changing this value it is desirable to have an adequate
// matching value |DeviceSensorEventPump::kDefaultPumpDelayMillis| in // matching value |DeviceSensorEventPump::kDefaultPumpDelayMillis| in
// content/renderer/device_orientation/device_sensor_event_pump.cc. // content/renderer/device_sensors/device_sensor_event_pump.cc.
const int kInertialSensorIntervalMillis = 50; const int kInertialSensorIntervalMillis = 50;
// Corresponding |kDefaultLightPumpDelayMillis| is in
// content/renderer/device_sensors/device_light_event_pump.cc.
const int kLightSensorIntervalMillis = 200;
} // namespace content } // namespace content
......
...@@ -26,15 +26,15 @@ namespace content { ...@@ -26,15 +26,15 @@ namespace content {
SensorManagerAndroid::SensorManagerAndroid() SensorManagerAndroid::SensorManagerAndroid()
: number_active_device_motion_sensors_(0), : number_active_device_motion_sensors_(0),
device_light_buffer_(NULL),
device_motion_buffer_(NULL), device_motion_buffer_(NULL),
device_orientation_buffer_(NULL), device_orientation_buffer_(NULL),
is_light_buffer_ready_(false),
is_motion_buffer_ready_(false), is_motion_buffer_ready_(false),
is_orientation_buffer_ready_(false) { is_orientation_buffer_ready_(false) {
memset(received_motion_data_, 0, sizeof(received_motion_data_)); memset(received_motion_data_, 0, sizeof(received_motion_data_));
device_orientation_.Reset( device_sensors_.Reset(Java_DeviceSensors_getInstance(
Java_DeviceSensors_getInstance( AttachCurrentThread(), base::android::GetApplicationContext()));
AttachCurrentThread(),
base::android::GetApplicationContext()));
} }
SensorManagerAndroid::~SensorManagerAndroid() { SensorManagerAndroid::~SensorManagerAndroid() {
...@@ -137,30 +137,79 @@ void SensorManagerAndroid::GotRotationRate( ...@@ -137,30 +137,79 @@ void SensorManagerAndroid::GotRotationRate(
} }
} }
void SensorManagerAndroid::GotLight(JNIEnv*, jobject, double value) {
base::AutoLock autolock(light_buffer_lock_);
if (!device_light_buffer_)
return;
device_light_buffer_->seqlock.WriteBegin();
device_light_buffer_->data.value = value;
device_light_buffer_->seqlock.WriteEnd();
}
bool SensorManagerAndroid::Start(EventType event_type) { bool SensorManagerAndroid::Start(EventType event_type) {
DCHECK(!device_orientation_.is_null()); DCHECK(!device_sensors_.is_null());
return Java_DeviceSensors_start( int rate_in_milliseconds = (event_type == kTypeLight)
AttachCurrentThread(), device_orientation_.obj(), ? kLightSensorIntervalMillis
reinterpret_cast<intptr_t>(this), static_cast<jint>(event_type), : kInertialSensorIntervalMillis;
kInertialSensorIntervalMillis); return Java_DeviceSensors_start(AttachCurrentThread(),
device_sensors_.obj(),
reinterpret_cast<intptr_t>(this),
static_cast<jint>(event_type),
rate_in_milliseconds);
} }
void SensorManagerAndroid::Stop(EventType event_type) { void SensorManagerAndroid::Stop(EventType event_type) {
DCHECK(!device_orientation_.is_null()); DCHECK(!device_sensors_.is_null());
Java_DeviceSensors_stop( Java_DeviceSensors_stop(AttachCurrentThread(),
AttachCurrentThread(), device_orientation_.obj(), device_sensors_.obj(),
static_cast<jint>(event_type)); static_cast<jint>(event_type));
} }
int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() { int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
DCHECK(!device_orientation_.is_null()); DCHECK(!device_sensors_.is_null());
return Java_DeviceSensors_getNumberActiveDeviceMotionSensors( return Java_DeviceSensors_getNumberActiveDeviceMotionSensors(
AttachCurrentThread(), device_orientation_.obj()); AttachCurrentThread(), device_sensors_.obj());
} }
// ----- Shared memory API methods // ----- Shared memory API methods
// --- Device Light
bool SensorManagerAndroid::StartFetchingDeviceLightData(
DeviceLightHardwareBuffer* buffer) {
DCHECK(buffer);
{
base::AutoLock autolock(light_buffer_lock_);
device_light_buffer_ = buffer;
SetLightBufferValue(-1);
}
bool success = Start(kTypeLight);
if (!success) {
base::AutoLock autolock(light_buffer_lock_);
SetLightBufferValue(std::numeric_limits<double>::infinity());
}
return success;
}
void SensorManagerAndroid::StopFetchingDeviceLightData() {
Stop(kTypeLight);
{
base::AutoLock autolock(light_buffer_lock_);
if (device_light_buffer_) {
SetLightBufferValue(-1);
device_light_buffer_ = NULL;
}
}
}
void SensorManagerAndroid::SetLightBufferValue(double lux) {
device_light_buffer_->seqlock.WriteBegin();
device_light_buffer_->data.value = lux;
device_light_buffer_->seqlock.WriteEnd();
}
// --- Device Motion // --- Device Motion
bool SensorManagerAndroid::StartFetchingDeviceMotionData( bool SensorManagerAndroid::StartFetchingDeviceMotionData(
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/device_sensors/device_light_hardware_buffer.h"
#include "content/common/device_sensors/device_motion_hardware_buffer.h" #include "content/common/device_sensors/device_motion_hardware_buffer.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h" #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
...@@ -16,7 +17,7 @@ template<typename T> struct DefaultSingletonTraits; ...@@ -16,7 +17,7 @@ template<typename T> struct DefaultSingletonTraits;
namespace content { namespace content {
// Android implementation of Device Orientation API. // Android implementation of Device {Motion|Orientation|Light} API.
// //
// Android's SensorManager has a push API, so when Got*() methods are called // Android's SensorManager has a push API, so when Got*() methods are called
// by the system the browser process puts the received data into a shared // by the system the browser process puts the received data into a shared
...@@ -30,6 +31,7 @@ class CONTENT_EXPORT SensorManagerAndroid { ...@@ -30,6 +31,7 @@ class CONTENT_EXPORT SensorManagerAndroid {
static SensorManagerAndroid* GetInstance(); static SensorManagerAndroid* GetInstance();
// Called from Java via JNI. // Called from Java via JNI.
void GotLight(JNIEnv*, jobject, double value);
void GotOrientation(JNIEnv*, jobject, void GotOrientation(JNIEnv*, jobject,
double alpha, double beta, double gamma); double alpha, double beta, double gamma);
void GotAcceleration(JNIEnv*, jobject, void GotAcceleration(JNIEnv*, jobject,
...@@ -40,6 +42,9 @@ class CONTENT_EXPORT SensorManagerAndroid { ...@@ -40,6 +42,9 @@ class CONTENT_EXPORT SensorManagerAndroid {
double alpha, double beta, double gamma); double alpha, double beta, double gamma);
// Shared memory related methods. // Shared memory related methods.
bool StartFetchingDeviceLightData(DeviceLightHardwareBuffer* buffer);
void StopFetchingDeviceLightData();
bool StartFetchingDeviceMotionData(DeviceMotionHardwareBuffer* buffer); bool StartFetchingDeviceMotionData(DeviceMotionHardwareBuffer* buffer);
void StopFetchingDeviceMotionData(); void StopFetchingDeviceMotionData();
...@@ -49,11 +54,12 @@ class CONTENT_EXPORT SensorManagerAndroid { ...@@ -49,11 +54,12 @@ class CONTENT_EXPORT SensorManagerAndroid {
protected: protected:
enum EventType { enum EventType {
// These constants should match DEVICE_ORIENTATION and DEVICE_MOTION // These constants should match DEVICE_ORIENTATION, DEVICE_MOTION and
// constants in content/public/android/java/src/org/chromium/content/ // DEVICE_LIGHT constants in content/public/android/java/src/org/
// browser/DeviceMotionAndOrientation.java // chromium/content/browser/DeviceSensors.java
kTypeOrientation = 0, kTypeOrientation = 0,
kTypeMotion = 1 kTypeMotion = 1,
kTypeLight = 2
}; };
SensorManagerAndroid(); SensorManagerAndroid();
...@@ -73,21 +79,26 @@ class CONTENT_EXPORT SensorManagerAndroid { ...@@ -73,21 +79,26 @@ class CONTENT_EXPORT SensorManagerAndroid {
RECEIVED_MOTION_DATA_MAX = 3, RECEIVED_MOTION_DATA_MAX = 3,
}; };
void SetLightBufferValue(double lux);
void CheckMotionBufferReadyToRead(); void CheckMotionBufferReadyToRead();
void SetMotionBufferReadyStatus(bool ready); void SetMotionBufferReadyStatus(bool ready);
void ClearInternalMotionBuffers(); void ClearInternalMotionBuffers();
void SetOrientationBufferReadyStatus(bool ready); void SetOrientationBufferReadyStatus(bool ready);
// The Java provider of orientation info. // The Java provider of sensors info.
base::android::ScopedJavaGlobalRef<jobject> device_orientation_; base::android::ScopedJavaGlobalRef<jobject> device_sensors_;
int number_active_device_motion_sensors_; int number_active_device_motion_sensors_;
int received_motion_data_[RECEIVED_MOTION_DATA_MAX]; int received_motion_data_[RECEIVED_MOTION_DATA_MAX];
DeviceLightHardwareBuffer* device_light_buffer_;
DeviceMotionHardwareBuffer* device_motion_buffer_; DeviceMotionHardwareBuffer* device_motion_buffer_;
DeviceOrientationHardwareBuffer* device_orientation_buffer_; DeviceOrientationHardwareBuffer* device_orientation_buffer_;
bool is_light_buffer_ready_;
bool is_motion_buffer_ready_; bool is_motion_buffer_ready_;
bool is_orientation_buffer_ready_; bool is_orientation_buffer_ready_;
base::Lock light_buffer_lock_;
base::Lock motion_buffer_lock_; base::Lock motion_buffer_lock_;
base::Lock orientation_buffer_lock_; base::Lock orientation_buffer_lock_;
......
...@@ -42,10 +42,12 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid { ...@@ -42,10 +42,12 @@ class FakeSensorManagerAndroid : public SensorManagerAndroid {
class AndroidSensorManagerTest : public testing::Test { class AndroidSensorManagerTest : public testing::Test {
protected: protected:
AndroidSensorManagerTest() { AndroidSensorManagerTest() {
light_buffer_.reset(new DeviceLightHardwareBuffer);
motion_buffer_.reset(new DeviceMotionHardwareBuffer); motion_buffer_.reset(new DeviceMotionHardwareBuffer);
orientation_buffer_.reset(new DeviceOrientationHardwareBuffer); orientation_buffer_.reset(new DeviceOrientationHardwareBuffer);
} }
scoped_ptr<DeviceLightHardwareBuffer> light_buffer_;
scoped_ptr<DeviceMotionHardwareBuffer> motion_buffer_; scoped_ptr<DeviceMotionHardwareBuffer> motion_buffer_;
scoped_ptr<DeviceOrientationHardwareBuffer> orientation_buffer_; scoped_ptr<DeviceOrientationHardwareBuffer> orientation_buffer_;
}; };
...@@ -142,6 +144,19 @@ TEST_F(AndroidSensorManagerTest, DeviceOrientationSensorsActive) { ...@@ -142,6 +144,19 @@ TEST_F(AndroidSensorManagerTest, DeviceOrientationSensorsActive) {
ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive); ASSERT_FALSE(orientation_buffer_->data.allAvailableSensorsAreActive);
} }
// DeviceLight
TEST_F(AndroidSensorManagerTest, DeviceLightSensorsActive) {
FakeSensorManagerAndroid::Register(base::android::AttachCurrentThread());
FakeSensorManagerAndroid sensorManager;
sensorManager.StartFetchingDeviceLightData(light_buffer_.get());
sensorManager.GotLight(0, 0, 100);
ASSERT_EQ(100, light_buffer_->data.value);
sensorManager.StopFetchingDeviceLightData();
ASSERT_EQ(-1, light_buffer_->data.value);
}
} // namespace } // namespace
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "content/browser/browser_main_loop.h" #include "content/browser/browser_main_loop.h"
#include "content/browser/browser_plugin/browser_plugin_message_filter.h" #include "content/browser/browser_plugin/browser_plugin_message_filter.h"
#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/device_sensors/device_light_message_filter.h"
#include "content/browser/device_sensors/device_motion_message_filter.h" #include "content/browser/device_sensors/device_motion_message_filter.h"
#include "content/browser/device_sensors/device_orientation_message_filter.h" #include "content/browser/device_sensors/device_orientation_message_filter.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
...@@ -866,6 +867,7 @@ void RenderProcessHostImpl::CreateMessageFilters() { ...@@ -866,6 +867,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
storage_partition_impl_->GetQuotaManager(), storage_partition_impl_->GetQuotaManager(),
GetContentClient()->browser()->CreateQuotaPermissionContext())); GetContentClient()->browser()->CreateQuotaPermissionContext()));
AddFilter(new GamepadBrowserMessageFilter()); AddFilter(new GamepadBrowserMessageFilter());
AddFilter(new DeviceLightMessageFilter());
AddFilter(new DeviceMotionMessageFilter()); AddFilter(new DeviceMotionMessageFilter());
AddFilter(new DeviceOrientationMessageFilter()); AddFilter(new DeviceOrientationMessageFilter());
AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER)); AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
......
...@@ -476,6 +476,8 @@ ...@@ -476,6 +476,8 @@
'browser/device_sensors/data_fetcher_shared_memory_win.cc', 'browser/device_sensors/data_fetcher_shared_memory_win.cc',
'browser/device_sensors/device_inertial_sensor_service.cc', 'browser/device_sensors/device_inertial_sensor_service.cc',
'browser/device_sensors/device_inertial_sensor_service.h', 'browser/device_sensors/device_inertial_sensor_service.h',
'browser/device_sensors/device_light_message_filter.cc',
'browser/device_sensors/device_light_message_filter.h',
'browser/device_sensors/device_motion_message_filter.cc', 'browser/device_sensors/device_motion_message_filter.cc',
'browser/device_sensors/device_motion_message_filter.h', 'browser/device_sensors/device_motion_message_filter.h',
'browser/device_sensors/device_orientation_message_filter.cc', 'browser/device_sensors/device_orientation_message_filter.cc',
......
...@@ -25,12 +25,12 @@ import java.util.Set; ...@@ -25,12 +25,12 @@ import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
/** /**
* Android implementation of the device motion and orientation APIs. * Android implementation of the device {motion|orientation|light} APIs.
*/ */
@JNINamespace("content") @JNINamespace("content")
class DeviceSensors implements SensorEventListener { class DeviceSensors implements SensorEventListener {
private static final String TAG = "DeviceMotionAndOrientation"; private static final String TAG = "DeviceSensors";
// These fields are lazily initialized by getHandler(). // These fields are lazily initialized by getHandler().
private Thread mThread; private Thread mThread;
...@@ -65,6 +65,7 @@ class DeviceSensors implements SensorEventListener { ...@@ -65,6 +65,7 @@ class DeviceSensors implements SensorEventListener {
*/ */
static final int DEVICE_ORIENTATION = 0; static final int DEVICE_ORIENTATION = 0;
static final int DEVICE_MOTION = 1; static final int DEVICE_MOTION = 1;
static final int DEVICE_LIGHT = 2;
static final Set<Integer> DEVICE_ORIENTATION_SENSORS = CollectionUtil.newHashSet( static final Set<Integer> DEVICE_ORIENTATION_SENSORS = CollectionUtil.newHashSet(
Sensor.TYPE_ROTATION_VECTOR); Sensor.TYPE_ROTATION_VECTOR);
...@@ -73,9 +74,12 @@ class DeviceSensors implements SensorEventListener { ...@@ -73,9 +74,12 @@ class DeviceSensors implements SensorEventListener {
Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER,
Sensor.TYPE_LINEAR_ACCELERATION, Sensor.TYPE_LINEAR_ACCELERATION,
Sensor.TYPE_GYROSCOPE); Sensor.TYPE_GYROSCOPE);
static final Set<Integer> DEVICE_LIGHT_SENSORS = CollectionUtil.newHashSet(
Sensor.TYPE_LIGHT);
@VisibleForTesting @VisibleForTesting
final Set<Integer> mActiveSensors = new HashSet<Integer>(); final Set<Integer> mActiveSensors = new HashSet<Integer>();
boolean mDeviceLightIsActive = false;
boolean mDeviceMotionIsActive = false; boolean mDeviceMotionIsActive = false;
boolean mDeviceOrientationIsActive = false; boolean mDeviceOrientationIsActive = false;
...@@ -91,7 +95,7 @@ class DeviceSensors implements SensorEventListener { ...@@ -91,7 +95,7 @@ class DeviceSensors implements SensorEventListener {
* @param rateInMilliseconds Requested callback rate in milliseconds. The * @param rateInMilliseconds Requested callback rate in milliseconds. The
* actual rate may be higher. Unwanted events should be ignored. * actual rate may be higher. Unwanted events should be ignored.
* @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or * @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or
* DEVICE_MOTION. * DEVICE_MOTION or DEVICE_LIGHT.
* @return True on success. * @return True on success.
*/ */
@CalledByNative @CalledByNative
...@@ -107,6 +111,9 @@ class DeviceSensors implements SensorEventListener { ...@@ -107,6 +111,9 @@ class DeviceSensors implements SensorEventListener {
// note: device motion spec does not require all sensors to be available // note: device motion spec does not require all sensors to be available
success = registerSensors(DEVICE_MOTION_SENSORS, rateInMilliseconds, false); success = registerSensors(DEVICE_MOTION_SENSORS, rateInMilliseconds, false);
break; break;
case DEVICE_LIGHT:
success = registerSensors(DEVICE_LIGHT_SENSORS, rateInMilliseconds, true);
break;
default: default:
Log.e(TAG, "Unknown event type: " + eventType); Log.e(TAG, "Unknown event type: " + eventType);
return false; return false;
...@@ -131,7 +138,7 @@ class DeviceSensors implements SensorEventListener { ...@@ -131,7 +138,7 @@ class DeviceSensors implements SensorEventListener {
* if they are still in use by a different event type. * if they are still in use by a different event type.
* *
* @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or * @param eventType Type of event to listen to, can be either DEVICE_ORIENTATION or
* DEVICE_MOTION. * DEVICE_MOTION or DEVICE_LIGHT.
* We strictly guarantee that the corresponding native*() methods will not be called * We strictly guarantee that the corresponding native*() methods will not be called
* after this method returns. * after this method returns.
*/ */
...@@ -144,8 +151,22 @@ class DeviceSensors implements SensorEventListener { ...@@ -144,8 +151,22 @@ class DeviceSensors implements SensorEventListener {
if (mDeviceMotionIsActive) { if (mDeviceMotionIsActive) {
sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS); sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS);
} }
if (mDeviceLightIsActive) {
sensorsToRemainActive.addAll(DEVICE_LIGHT_SENSORS);
}
break; break;
case DEVICE_MOTION: case DEVICE_MOTION:
if (mDeviceOrientationIsActive) {
sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
}
if (mDeviceLightIsActive) {
sensorsToRemainActive.addAll(DEVICE_LIGHT_SENSORS);
}
break;
case DEVICE_LIGHT:
if (mDeviceMotionIsActive) {
sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS);
}
if (mDeviceOrientationIsActive) { if (mDeviceOrientationIsActive) {
sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS); sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
} }
...@@ -210,6 +231,11 @@ class DeviceSensors implements SensorEventListener { ...@@ -210,6 +231,11 @@ class DeviceSensors implements SensorEventListener {
} }
} }
break; break;
case Sensor.TYPE_LIGHT:
if (mDeviceLightIsActive) {
gotLight(values[0]);
}
break;
default: default:
// Unexpected // Unexpected
return; return;
...@@ -343,6 +369,9 @@ class DeviceSensors implements SensorEventListener { ...@@ -343,6 +369,9 @@ class DeviceSensors implements SensorEventListener {
case DEVICE_MOTION: case DEVICE_MOTION:
mDeviceMotionIsActive = value; mDeviceMotionIsActive = value;
return; return;
case DEVICE_LIGHT:
mDeviceLightIsActive = value;
return;
} }
} }
...@@ -424,6 +453,14 @@ class DeviceSensors implements SensorEventListener { ...@@ -424,6 +453,14 @@ class DeviceSensors implements SensorEventListener {
} }
} }
protected void gotLight(double value) {
synchronized (mNativePtrLock) {
if (mNativePtr != 0) {
nativeGotLight(mNativePtr, value);
}
}
}
private Handler getHandler() { private Handler getHandler() {
// TODO(timvolodine): Remove the mHandlerLock when sure that getHandler is not called // TODO(timvolodine): Remove the mHandlerLock when sure that getHandler is not called
// from multiple threads. This will be the case when device motion and device orientation // from multiple threads. This will be the case when device motion and device orientation
...@@ -481,6 +518,13 @@ class DeviceSensors implements SensorEventListener { ...@@ -481,6 +518,13 @@ class DeviceSensors implements SensorEventListener {
long nativeSensorManagerAndroid, long nativeSensorManagerAndroid,
double alpha, double beta, double gamma); double alpha, double beta, double gamma);
/**
* Device Light value from Ambient Light sensors.
*/
private native void nativeGotLight(
long nativeSensorManagerAndroid,
double value);
/** /**
* Need the an interface for SensorManager for testing. * Need the an interface for SensorManager for testing.
*/ */
......
...@@ -42,6 +42,7 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -42,6 +42,7 @@ public class DeviceSensorsTest extends AndroidTestCase {
DeviceSensors.DEVICE_MOTION_SENSORS)); DeviceSensors.DEVICE_MOTION_SENSORS));
assertTrue(mDeviceSensors.mDeviceMotionIsActive); assertTrue(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceOrientationIsActive); assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(), assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(),
mMockSensorManager.mNumRegistered); mMockSensorManager.mNumRegistered);
...@@ -60,6 +61,7 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -60,6 +61,7 @@ public class DeviceSensorsTest extends AndroidTestCase {
mDeviceSensors.mActiveSensors.containsAll( mDeviceSensors.mActiveSensors.containsAll(
DeviceSensors.DEVICE_ORIENTATION_SENSORS)); DeviceSensors.DEVICE_ORIENTATION_SENSORS));
assertFalse(mDeviceSensors.mDeviceMotionIsActive); assertFalse(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
assertTrue(mDeviceSensors.mDeviceOrientationIsActive); assertTrue(mDeviceSensors.mDeviceOrientationIsActive);
assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(), assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(),
...@@ -90,12 +92,27 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -90,12 +92,27 @@ public class DeviceSensorsTest extends AndroidTestCase {
assertEquals(union.size(), mDeviceSensors.mActiveSensors.size()); assertEquals(union.size(), mDeviceSensors.mActiveSensors.size());
assertTrue(mDeviceSensors.mDeviceMotionIsActive); assertTrue(mDeviceSensors.mDeviceMotionIsActive);
assertTrue(mDeviceSensors.mDeviceOrientationIsActive); assertTrue(mDeviceSensors.mDeviceOrientationIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
assertEquals(union.size(), mMockSensorManager.mNumRegistered); assertEquals(union.size(), mMockSensorManager.mNumRegistered);
assertEquals(0, mMockSensorManager.mNumUnRegistered); assertEquals(0, mMockSensorManager.mNumUnRegistered);
assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(), assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(),
mDeviceSensors.getNumberActiveDeviceMotionSensors()); mDeviceSensors.getNumberActiveDeviceMotionSensors());
} }
@SmallTest
public void testRegisterSensorsDeviceLight() {
boolean start = mDeviceSensors.start(0, DeviceSensors.DEVICE_LIGHT, 100);
assertTrue(start);
assertTrue(mDeviceSensors.mDeviceLightIsActive);
assertFalse(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
assertEquals(DeviceSensors.DEVICE_LIGHT_SENSORS.size(),
mMockSensorManager.mNumRegistered);
assertEquals(0, mMockSensorManager.mNumUnRegistered);
}
@SmallTest @SmallTest
public void testUnregisterSensorsDeviceMotion() { public void testUnregisterSensorsDeviceMotion() {
mDeviceSensors.start(0, DeviceSensors.DEVICE_MOTION, 100); mDeviceSensors.start(0, DeviceSensors.DEVICE_MOTION, 100);
...@@ -105,6 +122,7 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -105,6 +122,7 @@ public class DeviceSensorsTest extends AndroidTestCase {
mDeviceSensors.mActiveSensors.isEmpty()); mDeviceSensors.mActiveSensors.isEmpty());
assertFalse(mDeviceSensors.mDeviceMotionIsActive); assertFalse(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceOrientationIsActive); assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(), assertEquals(DeviceSensors.DEVICE_MOTION_SENSORS.size(),
mMockSensorManager.mNumUnRegistered); mMockSensorManager.mNumUnRegistered);
assertEquals(0, mDeviceSensors.getNumberActiveDeviceMotionSensors()); assertEquals(0, mDeviceSensors.getNumberActiveDeviceMotionSensors());
...@@ -119,6 +137,7 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -119,6 +137,7 @@ public class DeviceSensorsTest extends AndroidTestCase {
mDeviceSensors.mActiveSensors.isEmpty()); mDeviceSensors.mActiveSensors.isEmpty());
assertFalse(mDeviceSensors.mDeviceMotionIsActive); assertFalse(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceOrientationIsActive); assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(), assertEquals(DeviceSensors.DEVICE_ORIENTATION_SENSORS.size(),
mMockSensorManager.mNumUnRegistered); mMockSensorManager.mNumUnRegistered);
} }
...@@ -147,6 +166,32 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -147,6 +166,32 @@ public class DeviceSensorsTest extends AndroidTestCase {
assertEquals(0, mDeviceSensors.getNumberActiveDeviceMotionSensors()); assertEquals(0, mDeviceSensors.getNumberActiveDeviceMotionSensors());
} }
@SmallTest
public void testUnregisterSensorsLight() {
mDeviceSensors.start(0, DeviceSensors.DEVICE_LIGHT, 100);
mDeviceSensors.stop(DeviceSensors.DEVICE_LIGHT);
assertTrue("should contain no sensors",
mDeviceSensors.mActiveSensors.isEmpty());
assertFalse(mDeviceSensors.mDeviceMotionIsActive);
assertFalse(mDeviceSensors.mDeviceOrientationIsActive);
assertFalse(mDeviceSensors.mDeviceLightIsActive);
}
@SmallTest
public void testSensorChangedgotLight() {
boolean startLight = mDeviceSensors.start(0,
DeviceSensors.DEVICE_LIGHT, 100);
assertTrue(startLight);
assertTrue(mDeviceSensors.mDeviceLightIsActive);
float[] values = {200};
mDeviceSensors.sensorChanged(Sensor.TYPE_LIGHT, values);
mDeviceSensors.verifyCalls("gotLight");
mDeviceSensors.verifyValue(200);
}
@SmallTest @SmallTest
public void testSensorChangedgotOrientation() { public void testSensorChangedgotOrientation() {
boolean startOrientation = mDeviceSensors.start(0, boolean startOrientation = mDeviceSensors.start(0,
...@@ -329,6 +374,10 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -329,6 +374,10 @@ public class DeviceSensorsTest extends AndroidTestCase {
return new DeviceSensorsForTests(context); return new DeviceSensorsForTests(context);
} }
private void verifyValue(double v1) {
assertEquals(v1, mValue1);
}
private void verifyValues(double v1, double v2, double v3) { private void verifyValues(double v1, double v2, double v3) {
assertEquals(v1, mValue1); assertEquals(v1, mValue1);
assertEquals(v2, mValue2); assertEquals(v2, mValue2);
...@@ -345,6 +394,12 @@ public class DeviceSensorsTest extends AndroidTestCase { ...@@ -345,6 +394,12 @@ public class DeviceSensorsTest extends AndroidTestCase {
assertEquals(mCalls, names); assertEquals(mCalls, names);
} }
@Override
protected void gotLight(double light) {
mValue1 = light;
mCalls = mCalls.concat("gotLight");
}
@Override @Override
protected void gotOrientation(double alpha, double beta, double gamma) { protected void gotOrientation(double alpha, double beta, double gamma) {
mValue1 = alpha; mValue1 = alpha;
......
...@@ -37,13 +37,24 @@ bool DeviceLightEventPump::OnControlMessageReceived( ...@@ -37,13 +37,24 @@ bool DeviceLightEventPump::OnControlMessageReceived(
void DeviceLightEventPump::FireEvent() { void DeviceLightEventPump::FireEvent() {
DCHECK(listener()); DCHECK(listener());
DeviceLightData data; DeviceLightData data;
bool did_return_light_data = reader_->GetLatestData(&data); if (reader_->GetLatestData(&data) && ShouldFireEvent(data.value)) {
if (did_return_light_data && data.value != last_seen_data_) {
last_seen_data_ = data.value; last_seen_data_ = data.value;
listener()->didChangeDeviceLight(data.value); listener()->didChangeDeviceLight(data.value);
} }
} }
bool DeviceLightEventPump::ShouldFireEvent(double lux) const {
if (lux < 0)
return false;
if (lux == std::numeric_limits<double>::infinity()) {
// no sensor data can be provided, fire an Infinity event to Blink.
return true;
}
return lux != last_seen_data_;
}
bool DeviceLightEventPump::InitializeReader(base::SharedMemoryHandle handle) { bool DeviceLightEventPump::InitializeReader(base::SharedMemoryHandle handle) {
if (!reader_) if (!reader_)
reader_.reset(new DeviceLightSharedMemoryReader()); reader_.reset(new DeviceLightSharedMemoryReader());
......
...@@ -42,6 +42,9 @@ class CONTENT_EXPORT DeviceLightEventPump ...@@ -42,6 +42,9 @@ class CONTENT_EXPORT DeviceLightEventPump
virtual void SendStartMessage() OVERRIDE; virtual void SendStartMessage() OVERRIDE;
virtual void SendStopMessage() OVERRIDE; virtual void SendStopMessage() OVERRIDE;
private:
bool ShouldFireEvent(double data) const;
scoped_ptr<DeviceLightSharedMemoryReader> reader_; scoped_ptr<DeviceLightSharedMemoryReader> reader_;
double last_seen_data_; double last_seen_data_;
......
...@@ -111,6 +111,19 @@ TEST_F(DeviceLightEventPumpTest, DidStartPolling) { ...@@ -111,6 +111,19 @@ TEST_F(DeviceLightEventPumpTest, DidStartPolling) {
EXPECT_EQ(1, static_cast<double>(received_data.value)); EXPECT_EQ(1, static_cast<double>(received_data.value));
} }
TEST_F(DeviceLightEventPumpTest, FireAllNullEvent) {
base::MessageLoopForUI loop;
light_pump()->Start(listener());
light_pump()->OnDidStart(handle());
base::MessageLoop::current()->Run();
const DeviceLightData& received_data = listener()->data();
EXPECT_TRUE(listener()->did_change_device_light());
EXPECT_FALSE(received_data.value);
}
TEST_F(DeviceLightEventPumpTest, DidStartPollingValuesEqual) { TEST_F(DeviceLightEventPumpTest, DidStartPollingValuesEqual) {
base::MessageLoopForUI loop; base::MessageLoopForUI loop;
......
<html>
<head>
<title>DeviceLight one-off Infinity event test with alert</title>
</head>
<body>
<div id="status">FAIL</div>
</body>
<script type="text/javascript">
function checkLightEvent(event) {
return event.value == Infinity;
}
function onLight(event) {
window.removeEventListener('devicelight', onLight);
checkLightEvent(event) ? pass() : fail();
}
function pass() {
document.getElementById('status').innerHTML = 'PASS';
document.location = '#pass';
}
function fail() {
document.location = '#fail';
}
window.addEventListener('devicelight', onLight);
alert("suspend active DOM objects");
</script>
</html>
<html>
<head>
<title>DeviceLight test</title>
<script type="text/javascript">
function checkLightEvent(event) {
return event.value >= 0;
}
function onLight(event) {
if (checkLightEvent(event)) {
window.removeEventListener('devicelight', onLight);
pass();
} else {
fail();
}
}
function pass() {
document.getElementById('status').innerHTML = 'PASS';
document.location = '#pass';
}
function fail() {
document.location = '#fail';
}
</script>
</head>
<body onLoad="window.addEventListener('devicelight', onLight)">
<div id="status">FAIL</div>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment