Commit 1a016dba authored by dcheng@chromium.org's avatar dcheng@chromium.org

Revert of Generalize and refactor DeviceSensorEvent* architecture to support...

Revert of Generalize and refactor DeviceSensorEvent* architecture to support multi-event type targets. (https://codereview.chromium.org/315573002/)

Reason for revert:
Triggers assert in 
fast/dom/Window/property-access-on-cached-window-after-frame-navigated.html

Original issue's description:
> Generalize and refactor DeviceSensorEvent* architecture to support
> multi-event type targets.
> 
> This patch performs a significant refactoring of the
> DeviceSensorEvent{Controller,Dispatcher} and related classes.
> It provides new Base classes to allow simple implementation of
> APIs involving multi-event type non-window targets (e.g. Battery
> Status API). Additionally it makes the implementation of existing
> event-based APIs (device_orientation, device_light) simpler and
> more compact.
> 
> In particular the following new classes have been added:
> * DeviceEventControllerBase and DeviceEventDispatcherBase
> (derived from by the Battery Status API).
> * DeviceSingleWindowEventController is more specific and
> contains functionality necessary for single-event type window
> target APIs (used by Device Motion/Orientation and Device Light
> APIs).
> 
> BUG=122593, 360068
> NOTRY=true
> 
> Committed: https://src.chromium.org/viewvc/blink?view=rev&revision=175661

TBR=ch.dumez@samsung.com,abarth@chromium.org,jochen@chromium.org,tkent@chromium.org,timvolodine@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=122593, 360068

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

git-svn-id: svn://svn.chromium.org/blink/trunk@175673 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 76d93bc5
...@@ -1144,16 +1144,10 @@ ...@@ -1144,16 +1144,10 @@
'frame/DOMWindowTimers.h', 'frame/DOMWindowTimers.h',
'frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp', 'frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp',
'frame/DeprecatedScheduleStyleRecalcDuringLayout.h', 'frame/DeprecatedScheduleStyleRecalcDuringLayout.h',
'frame/DeviceEventControllerBase.cpp',
'frame/DeviceEventControllerBase.h',
'frame/DeviceEventDispatcherBase.cpp',
'frame/DeviceEventDispatcherBase.h',
'frame/DeviceSensorEventController.cpp', 'frame/DeviceSensorEventController.cpp',
'frame/DeviceSensorEventController.h', 'frame/DeviceSensorEventController.h',
'frame/DeviceSensorEventDispatcher.cpp', 'frame/DeviceSensorEventDispatcher.cpp',
'frame/DeviceSensorEventDispatcher.h', 'frame/DeviceSensorEventDispatcher.h',
'frame/DeviceSingleWindowEventController.cpp',
'frame/DeviceSingleWindowEventController.h',
'frame/EventHandlerRegistry.cpp', 'frame/EventHandlerRegistry.cpp',
'frame/EventHandlerRegistry.h', 'frame/EventHandlerRegistry.h',
'frame/Frame.cpp', 'frame/Frame.cpp',
......
// 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 "config.h"
#include "core/frame/DeviceEventControllerBase.h"
#include "core/page/Page.h"
namespace WebCore {
DeviceEventControllerBase::DeviceEventControllerBase(Page* page)
: PageLifecycleObserver(page)
, m_hasEventListener(false)
, m_isActive(false)
, m_timer(this, &DeviceEventControllerBase::oneShotCallback)
{
}
DeviceEventControllerBase::~DeviceEventControllerBase()
{
}
void DeviceEventControllerBase::oneShotCallback(Timer<DeviceEventControllerBase>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
ASSERT(hasLastData());
ASSERT(!m_timer.isActive());
didUpdateData();
}
void DeviceEventControllerBase::startUpdating()
{
if (m_isActive)
return;
if (hasLastData() && !m_timer.isActive()) {
// Make sure to fire the data as soon as possible.
m_timer.startOneShot(0, FROM_HERE);
}
registerWithDispatcher();
m_isActive = true;
}
void DeviceEventControllerBase::stopUpdating()
{
if (!m_isActive)
return;
if (m_timer.isActive())
m_timer.stop();
unregisterWithDispatcher();
m_isActive = false;
}
void DeviceEventControllerBase::pageVisibilityChanged()
{
if (!m_hasEventListener)
return;
if (page()->visibilityState() == PageVisibilityStateVisible)
startUpdating();
else
stopUpdating();
}
} // namespace WebCore
// 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 DeviceEventControllerBase_h
#define DeviceEventControllerBase_h
#include "core/page/PageLifecycleObserver.h"
#include "platform/Timer.h"
namespace WebCore {
// Base controller class for registering controllers with a dispatcher.
// It watches page visibility and calls stopUpdating when page is not visible.
// It provides a didUpdateData() callback method which is called when new data
// it available.
class DeviceEventControllerBase : public PageLifecycleObserver {
public:
void startUpdating();
void stopUpdating();
// This is called when new data becomes available.
virtual void didUpdateData() = 0;
protected:
explicit DeviceEventControllerBase(Page*);
virtual ~DeviceEventControllerBase();
virtual void registerWithDispatcher() = 0;
virtual void unregisterWithDispatcher() = 0;
// When true initiates a one-shot didUpdateData() when startUpdating() is called.
virtual bool hasLastData() = 0;
bool m_hasEventListener;
private:
// Inherited from PageLifecycleObserver.
virtual void pageVisibilityChanged() OVERRIDE FINAL;
void oneShotCallback(Timer<DeviceEventControllerBase>*);
bool m_isActive;
Timer<DeviceEventControllerBase> m_timer;
};
} // namespace WebCore
#endif // DeviceEventControllerBase_h
// 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 "config.h"
#include "core/frame/DeviceEventDispatcherBase.h"
#include "core/frame/DeviceEventControllerBase.h"
#include "wtf/TemporaryChange.h"
namespace WebCore {
DeviceEventDispatcherBase::DeviceEventDispatcherBase()
: m_needsPurge(false)
, m_isDispatching(false)
{
}
DeviceEventDispatcherBase::~DeviceEventDispatcherBase()
{
}
void DeviceEventDispatcherBase::addController(DeviceEventControllerBase* controller)
{
bool wasEmpty = m_controllers.isEmpty();
if (!m_controllers.contains(controller))
m_controllers.append(controller);
if (wasEmpty)
startListening();
}
void DeviceEventDispatcherBase::removeController(DeviceEventControllerBase* controller)
{
// Do not actually remove the controller from the vector, instead zero them out.
// The zeros are removed in these two cases:
// 1. either immediately if we are not dispatching any events,
// 2. or after events to all controllers have dispatched (see notifyControllers()).
// This is to correctly handle the re-entrancy case when a controller is destroyed
// while the events are still being dispatched.
size_t index = m_controllers.find(controller);
if (index == kNotFound)
return;
m_controllers[index] = 0;
m_needsPurge = true;
if (!m_isDispatching)
purgeControllers();
}
void DeviceEventDispatcherBase::purgeControllers()
{
ASSERT(m_needsPurge);
size_t i = 0;
while (i < m_controllers.size()) {
if (!m_controllers[i]) {
m_controllers[i] = m_controllers.last();
m_controllers.removeLast();
} else {
++i;
}
}
m_needsPurge = false;
if (m_controllers.isEmpty())
stopListening();
}
void DeviceEventDispatcherBase::notifyControllers()
{
{
TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
// Don't notify controllers removed or added during event dispatch.
size_t size = m_controllers.size();
for (size_t i = 0; i < size; ++i) {
if (m_controllers[i])
m_controllers[i]->didUpdateData();
}
}
if (m_needsPurge)
purgeControllers();
}
} // namespace WebCore
// 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 DeviceEventDispatcherBase_h
#define DeviceEventDispatcherBase_h
#include "wtf/Vector.h"
namespace WebCore {
class DeviceEventControllerBase;
class DeviceEventDispatcherBase {
public:
void addController(DeviceEventControllerBase*);
void removeController(DeviceEventControllerBase*);
protected:
DeviceEventDispatcherBase();
virtual ~DeviceEventDispatcherBase();
void notifyControllers();
virtual void startListening() = 0;
virtual void stopListening() = 0;
private:
void purgeControllers();
Vector<DeviceEventControllerBase*> m_controllers;
bool m_needsPurge;
bool m_isDispatching;
};
} // namespace WebCore
#endif // DeviceEventDispatcherBase_h
// 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 "config.h"
#include "core/frame/DeviceSingleWindowEventController.h"
#include "core/dom/Document.h"
#include "core/frame/DOMWindow.h"
#include "core/page/Page.h"
namespace WebCore {
DeviceSingleWindowEventController::DeviceSingleWindowEventController(Document& document)
: DeviceEventControllerBase(document.page())
, DOMWindowLifecycleObserver(document.domWindow())
, m_needsCheckingNullEvents(true)
, m_document(document)
{
}
DeviceSingleWindowEventController::~DeviceSingleWindowEventController()
{
}
void DeviceSingleWindowEventController::didUpdateData()
{
dispatchDeviceEvent(lastEvent());
}
void DeviceSingleWindowEventController::dispatchDeviceEvent(PassRefPtrWillBeRawPtr<Event> prpEvent)
{
if (!m_document.domWindow() || m_document.activeDOMObjectsAreSuspended() || m_document.activeDOMObjectsAreStopped())
return;
RefPtrWillBeRawPtr<Event> event = prpEvent;
m_document.domWindow()->dispatchEvent(event);
if (m_needsCheckingNullEvents) {
if (isNullEvent(event.get()))
stopUpdating();
else
m_needsCheckingNullEvents = false;
}
}
void DeviceSingleWindowEventController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType != eventTypeName())
return;
if (page() && page()->visibilityState() == PageVisibilityStateVisible)
startUpdating();
m_hasEventListener = true;
}
void DeviceSingleWindowEventController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType != eventTypeName() || window->hasEventListeners(eventTypeName()))
return;
stopUpdating();
m_hasEventListener = false;
}
void DeviceSingleWindowEventController::didRemoveAllEventListeners(DOMWindow*)
{
stopUpdating();
m_hasEventListener = false;
}
} // namespace WebCore
// 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 DeviceSingleWindowEventController_h
#define DeviceSingleWindowEventController_h
#include "core/frame/DOMWindowLifecycleObserver.h"
#include "core/frame/DeviceEventControllerBase.h"
#include "platform/heap/Handle.h"
namespace WebCore {
class Document;
class Event;
class DeviceSingleWindowEventController : public DeviceEventControllerBase, public DOMWindowLifecycleObserver {
public:
// Inherited from DeviceEventControllerBase.
virtual void didUpdateData() OVERRIDE;
// Inherited from DOMWindowLifecycleObserver.
virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
protected:
explicit DeviceSingleWindowEventController(Document&);
virtual ~DeviceSingleWindowEventController();
void dispatchDeviceEvent(const PassRefPtrWillBeRawPtr<Event>);
virtual PassRefPtrWillBeRawPtr<Event> lastEvent() const = 0;
virtual const AtomicString& eventTypeName() const = 0;
virtual bool isNullEvent(Event*) const = 0;
private:
bool m_needsCheckingNullEvents;
Document& m_document;
};
} // namespace WebCore
#endif // DeviceSingleWindowEventController_h
...@@ -25,17 +25,63 @@ BatteryDispatcher::~BatteryDispatcher() ...@@ -25,17 +25,63 @@ BatteryDispatcher::~BatteryDispatcher()
{ {
} }
void BatteryDispatcher::addClient(BatteryManager* batteryManager)
{
addController(batteryManager);
}
void BatteryDispatcher::removeClient(BatteryManager* batteryManager)
{
removeController(batteryManager);
}
void BatteryDispatcher::updateBatteryStatus(const blink::WebBatteryStatus& batteryStatus) void BatteryDispatcher::updateBatteryStatus(const blink::WebBatteryStatus& batteryStatus)
{ {
RefPtr<BatteryStatus> oldStatus = m_batteryStatus;
m_batteryStatus = BatteryStatus::create(batteryStatus.charging, batteryStatus.chargingTime, batteryStatus.dischargingTime, batteryStatus.level); m_batteryStatus = BatteryStatus::create(batteryStatus.charging, batteryStatus.chargingTime, batteryStatus.dischargingTime, batteryStatus.level);
notifyControllers();
if (oldStatus) {
if (m_batteryStatus->charging() != oldStatus->charging())
didChangeBatteryStatus(EventTypeNames::chargingchange);
if (m_batteryStatus->charging() && m_batteryStatus->chargingTime() != oldStatus->chargingTime())
didChangeBatteryStatus(EventTypeNames::chargingtimechange);
if (!m_batteryStatus->charging() && m_batteryStatus->dischargingTime() != oldStatus->dischargingTime())
didChangeBatteryStatus(EventTypeNames::dischargingtimechange);
if (m_batteryStatus->level() != oldStatus->level())
didChangeBatteryStatus(EventTypeNames::levelchange);
} else {
// There was no previous state.
didChangeBatteryStatus(EventTypeNames::chargingchange);
didChangeBatteryStatus(EventTypeNames::chargingtimechange);
didChangeBatteryStatus(EventTypeNames::dischargingtimechange);
didChangeBatteryStatus(EventTypeNames::levelchange);
}
} }
BatteryStatus* BatteryDispatcher::latestData() const BatteryStatus* BatteryDispatcher::getLatestData()
{ {
return m_batteryStatus.get(); return m_batteryStatus.get();
} }
void BatteryDispatcher::didChangeBatteryStatus(const AtomicString& eventType)
{
RefPtrWillBeRawPtr<Event> event = Event::create(eventType);
{
TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
// Don't fire listeners removed or added during event dispatch.
size_t size = m_controllers.size();
for (size_t i = 0; i < size; ++i) {
if (m_controllers[i])
static_cast<BatteryManager*>(m_controllers[i])->didChangeBatteryStatus(event);
}
}
if (m_needsPurge)
purgeControllers();
}
void BatteryDispatcher::startListening() void BatteryDispatcher::startListening()
{ {
blink::Platform::current()->setBatteryStatusListener(this); blink::Platform::current()->setBatteryStatusListener(this);
...@@ -44,7 +90,6 @@ void BatteryDispatcher::startListening() ...@@ -44,7 +90,6 @@ void BatteryDispatcher::startListening()
void BatteryDispatcher::stopListening() void BatteryDispatcher::stopListening()
{ {
blink::Platform::current()->setBatteryStatusListener(0); blink::Platform::current()->setBatteryStatusListener(0);
m_batteryStatus.clear();
} }
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef BatteryDispatcher_h #ifndef BatteryDispatcher_h
#define BatteryDispatcher_h #define BatteryDispatcher_h
#include "core/frame/DeviceEventDispatcherBase.h" #include "core/frame/DeviceSensorEventDispatcher.h"
#include "modules/battery/BatteryManager.h" #include "modules/battery/BatteryManager.h"
#include "modules/battery/BatteryStatus.h" #include "modules/battery/BatteryStatus.h"
#include "public/platform/WebBatteryStatusListener.h" #include "public/platform/WebBatteryStatusListener.h"
...@@ -16,20 +16,22 @@ class WebBatteryStatus; ...@@ -16,20 +16,22 @@ class WebBatteryStatus;
namespace WebCore { namespace WebCore {
class BatteryDispatcher FINAL : public DeviceEventDispatcherBase, public blink::WebBatteryStatusListener { class BatteryDispatcher FINAL : public DeviceSensorEventDispatcher, public blink::WebBatteryStatusListener {
public: public:
static BatteryDispatcher& instance(); static BatteryDispatcher& instance();
virtual ~BatteryDispatcher(); virtual ~BatteryDispatcher();
BatteryStatus* latestData(); void addClient(BatteryManager*);
void removeClient(BatteryManager*);
// Inherited from blink::WebBatteryStatusListener. const BatteryStatus* getLatestData();
virtual void updateBatteryStatus(const blink::WebBatteryStatus&) OVERRIDE; virtual void updateBatteryStatus(const blink::WebBatteryStatus&) OVERRIDE;
private: private:
BatteryDispatcher(); BatteryDispatcher();
// Inherited from DeviceEventDispatcherBase. void didChangeBatteryStatus(const AtomicString& eventType);
virtual void startListening() OVERRIDE; virtual void startListening() OVERRIDE;
virtual void stopListening() OVERRIDE; virtual void stopListening() OVERRIDE;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "RuntimeEnabledFeatures.h" #include "RuntimeEnabledFeatures.h"
#include "modules/battery/BatteryDispatcher.h" #include "modules/battery/BatteryDispatcher.h"
#include "modules/battery/BatteryStatus.h" #include "modules/battery/BatteryStatus.h"
#include <limits>
namespace WebCore { namespace WebCore {
...@@ -24,8 +25,7 @@ BatteryManager::~BatteryManager() ...@@ -24,8 +25,7 @@ BatteryManager::~BatteryManager()
BatteryManager::BatteryManager(ExecutionContext* context) BatteryManager::BatteryManager(ExecutionContext* context)
: ActiveDOMObject(context) : ActiveDOMObject(context)
, DeviceEventControllerBase(toDocument(context)->page()) , DeviceSensorEventController(toDocument(context)->page())
, m_batteryStatus(BatteryStatus::create())
{ {
m_hasEventListener = true; m_hasEventListener = true;
startUpdating(); startUpdating();
...@@ -33,63 +33,72 @@ BatteryManager::BatteryManager(ExecutionContext* context) ...@@ -33,63 +33,72 @@ BatteryManager::BatteryManager(ExecutionContext* context)
bool BatteryManager::charging() bool BatteryManager::charging()
{ {
return m_batteryStatus->charging(); if (const BatteryStatus* lastData = BatteryDispatcher::instance().getLatestData())
return lastData->charging();
return true;
} }
double BatteryManager::chargingTime() double BatteryManager::chargingTime()
{ {
return m_batteryStatus->chargingTime(); if (const BatteryStatus* lastData = BatteryDispatcher::instance().getLatestData())
return lastData->chargingTime();
return 0;
} }
double BatteryManager::dischargingTime() double BatteryManager::dischargingTime()
{ {
return m_batteryStatus->dischargingTime(); if (const BatteryStatus* lastData = BatteryDispatcher::instance().getLatestData())
return lastData->dischargingTime();
return std::numeric_limits<double>::infinity();
} }
double BatteryManager::level() double BatteryManager::level()
{ {
return m_batteryStatus->level(); if (const BatteryStatus* lastData = BatteryDispatcher::instance().getLatestData())
return lastData->level();
return 1;
} }
void BatteryManager::didUpdateData() void BatteryManager::didChangeBatteryStatus(PassRefPtrWillBeRawPtr<Event> event)
{ {
ASSERT(RuntimeEnabledFeatures::batteryStatusEnabled()); ASSERT(RuntimeEnabledFeatures::batteryStatusEnabled());
RefPtr<BatteryStatus> oldStatus = m_batteryStatus; dispatchEvent(event);
m_batteryStatus = BatteryDispatcher::instance().latestData();
// BatteryDispatcher also holds a reference to m_batteryStatus.
ASSERT(m_batteryStatus->refCount() == 2);
Document* document = toDocument(executionContext());
if (document->activeDOMObjectsAreSuspended() || document->activeDOMObjectsAreStopped())
return;
ASSERT(oldStatus);
if (m_batteryStatus->charging() != oldStatus->charging())
dispatchEvent(Event::create(EventTypeNames::chargingchange));
if (m_batteryStatus->chargingTime() != oldStatus->chargingTime())
dispatchEvent(Event::create(EventTypeNames::chargingtimechange));
if (m_batteryStatus->dischargingTime() != oldStatus->dischargingTime())
dispatchEvent(Event::create(EventTypeNames::dischargingtimechange));
if (m_batteryStatus->level() != oldStatus->level())
dispatchEvent(Event::create(EventTypeNames::levelchange));
} }
void BatteryManager::registerWithDispatcher() void BatteryManager::registerWithDispatcher()
{ {
BatteryDispatcher::instance().addController(this); BatteryDispatcher::instance().addClient(this);
} }
void BatteryManager::unregisterWithDispatcher() void BatteryManager::unregisterWithDispatcher()
{ {
BatteryDispatcher::instance().removeController(this); BatteryDispatcher::instance().removeClient(this);
} }
bool BatteryManager::hasLastData() bool BatteryManager::hasLastData()
{ {
return BatteryDispatcher::instance().latestData(); return false;
}
PassRefPtrWillBeRawPtr<Event> BatteryManager::getLastEvent()
{
// Events are dispached via BatteryManager::didChangeBatteryStatus()
return nullptr;
}
bool BatteryManager::isNullEvent(Event*)
{
return false;
}
Document* BatteryManager::document()
{
return toDocument(executionContext());
} }
void BatteryManager::suspend() void BatteryManager::suspend()
......
...@@ -7,16 +7,15 @@ ...@@ -7,16 +7,15 @@
#include "core/dom/ContextLifecycleObserver.h" #include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "core/frame/DeviceEventControllerBase.h" #include "core/frame/DeviceSensorEventController.h"
#include "modules/EventTargetModules.h" #include "modules/EventTargetModules.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
namespace WebCore { namespace WebCore {
class BatteryStatus;
class Navigator; class Navigator;
class BatteryManager FINAL : public RefCountedWillBeRefCountedGarbageCollected<BatteryManager>, public ActiveDOMObject, public DeviceEventControllerBase, public EventTargetWithInlineData { class BatteryManager FINAL : public RefCountedWillBeRefCountedGarbageCollected<BatteryManager>, public ActiveDOMObject, public DeviceSensorEventController, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(BatteryManager); REFCOUNTED_EVENT_TARGET(BatteryManager);
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BatteryManager); WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BatteryManager);
public: public:
...@@ -37,11 +36,7 @@ public: ...@@ -37,11 +36,7 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(dischargingtimechange); DEFINE_ATTRIBUTE_EVENT_LISTENER(dischargingtimechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(levelchange); DEFINE_ATTRIBUTE_EVENT_LISTENER(levelchange);
// Inherited from DeviceEventControllerBase. void didChangeBatteryStatus(PassRefPtrWillBeRawPtr<Event>);
virtual void didUpdateData() OVERRIDE;
virtual void registerWithDispatcher() OVERRIDE;
virtual void unregisterWithDispatcher() OVERRIDE;
virtual bool hasLastData() OVERRIDE;
// ActiveDOMObject implementation. // ActiveDOMObject implementation.
virtual bool canSuspend() const { return true; } virtual bool canSuspend() const { return true; }
...@@ -49,10 +44,16 @@ public: ...@@ -49,10 +44,16 @@ public:
virtual void resume() OVERRIDE; virtual void resume() OVERRIDE;
virtual void stop() OVERRIDE; virtual void stop() OVERRIDE;
// DeviceSensorEventController
virtual void registerWithDispatcher() OVERRIDE;
virtual void unregisterWithDispatcher() OVERRIDE;
virtual bool hasLastData() OVERRIDE;
virtual PassRefPtrWillBeRawPtr<Event> getLastEvent() OVERRIDE;
virtual bool isNullEvent(Event*) OVERRIDE;
virtual Document* document() OVERRIDE;
private: private:
explicit BatteryManager(ExecutionContext*); explicit BatteryManager(ExecutionContext*);
RefPtr<BatteryStatus> m_batteryStatus;
}; };
} }
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
namespace WebCore { namespace WebCore {
DeviceLightController::DeviceLightController(Document& document) DeviceLightController::DeviceLightController(Document& document)
: DeviceSingleWindowEventController(document) : DeviceSensorEventController(document.page())
, DOMWindowLifecycleObserver(document.domWindow())
, m_document(document)
{ {
} }
...@@ -24,6 +26,11 @@ DeviceLightController::~DeviceLightController() ...@@ -24,6 +26,11 @@ DeviceLightController::~DeviceLightController()
stopUpdating(); stopUpdating();
} }
void DeviceLightController::didChangeDeviceLight(double value)
{
dispatchDeviceEvent(DeviceLightEvent::create(EventTypeNames::devicelight, value));
}
const char* DeviceLightController::supplementName() const char* DeviceLightController::supplementName()
{ {
return "DeviceLightController"; return "DeviceLightController";
...@@ -44,31 +51,55 @@ bool DeviceLightController::hasLastData() ...@@ -44,31 +51,55 @@ bool DeviceLightController::hasLastData()
return DeviceLightDispatcher::instance().latestDeviceLightData() >= 0; return DeviceLightDispatcher::instance().latestDeviceLightData() >= 0;
} }
void DeviceLightController::registerWithDispatcher() PassRefPtrWillBeRawPtr<Event> DeviceLightController::getLastEvent()
{ {
DeviceLightDispatcher::instance().addController(this); return DeviceLightEvent::create(EventTypeNames::devicelight,
DeviceLightDispatcher::instance().latestDeviceLightData());
} }
void DeviceLightController::unregisterWithDispatcher() void DeviceLightController::registerWithDispatcher()
{ {
DeviceLightDispatcher::instance().removeController(this); DeviceLightDispatcher::instance().addDeviceLightController(this);
} }
PassRefPtrWillBeRawPtr<Event> DeviceLightController::lastEvent() const void DeviceLightController::unregisterWithDispatcher()
{ {
return DeviceLightEvent::create(EventTypeNames::devicelight, DeviceLightDispatcher::instance().removeDeviceLightController(this);
DeviceLightDispatcher::instance().latestDeviceLightData());
} }
bool DeviceLightController::isNullEvent(Event* event) const bool DeviceLightController::isNullEvent(Event* event)
{ {
DeviceLightEvent* lightEvent = toDeviceLightEvent(event); DeviceLightEvent* lightEvent = toDeviceLightEvent(event);
return lightEvent->value() == std::numeric_limits<double>::infinity(); return lightEvent->value() == std::numeric_limits<double>::infinity();
} }
const AtomicString& DeviceLightController::eventTypeName() const Document* DeviceLightController::document()
{
return &m_document;
}
void DeviceLightController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType == EventTypeNames::devicelight && RuntimeEnabledFeatures::deviceLightEnabled()) {
if (page() && page()->visibilityState() == PageVisibilityStateVisible)
startUpdating();
m_hasEventListener = true;
}
}
void DeviceLightController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
{ {
return EventTypeNames::devicelight; if (eventType != EventTypeNames::devicelight || window->hasEventListeners(EventTypeNames::devicelight))
return;
stopUpdating();
m_hasEventListener = false;
}
void DeviceLightController::didRemoveAllEventListeners(DOMWindow* window)
{
stopUpdating();
m_hasEventListener = false;
} }
} // namespace WebCore } // namespace WebCore
...@@ -6,14 +6,15 @@ ...@@ -6,14 +6,15 @@
#define DeviceLightController_h #define DeviceLightController_h
#include "core/dom/DocumentSupplementable.h" #include "core/dom/DocumentSupplementable.h"
#include "core/frame/DeviceSingleWindowEventController.h" #include "core/frame/DOMWindowLifecycleObserver.h"
#include "core/frame/DeviceSensorEventController.h"
#include "modules/EventModules.h"
namespace WebCore { namespace WebCore {
class DOMWindow; class DOMWindow;
class Event;
class DeviceLightController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceLightController>, public DeviceSingleWindowEventController, public DocumentSupplement { class DeviceLightController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceLightController>, public DeviceSensorEventController, public DocumentSupplement, public DOMWindowLifecycleObserver {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceLightController); WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceLightController);
public: public:
virtual ~DeviceLightController(); virtual ~DeviceLightController();
...@@ -21,18 +22,24 @@ public: ...@@ -21,18 +22,24 @@ public:
static const char* supplementName(); static const char* supplementName();
static DeviceLightController& from(Document&); static DeviceLightController& from(Document&);
void didChangeDeviceLight(double);
private: private:
explicit DeviceLightController(Document&); explicit DeviceLightController(Document&);
// Inherited from DeviceEventControllerBase.
virtual void registerWithDispatcher() OVERRIDE; virtual void registerWithDispatcher() OVERRIDE;
virtual void unregisterWithDispatcher() OVERRIDE; virtual void unregisterWithDispatcher() OVERRIDE;
// Inherited from DOMWindowLifecycleObserver.
virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
virtual bool hasLastData() OVERRIDE; virtual bool hasLastData() OVERRIDE;
virtual PassRefPtrWillBeRawPtr<Event> getLastEvent() OVERRIDE;
virtual bool isNullEvent(Event*) OVERRIDE;
virtual Document* document() OVERRIDE;
// Inherited from DeviceSingleWindowEventController. Document& m_document;
virtual PassRefPtrWillBeRawPtr<Event> lastEvent() const OVERRIDE;
virtual const AtomicString& eventTypeName() const OVERRIDE;
virtual bool isNullEvent(Event*) const OVERRIDE;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "core/frame/DeviceSensorEventDispatcher.h" #include "core/frame/DeviceSensorEventDispatcher.h"
#include "modules/device_light/DeviceLightController.h" #include "modules/device_light/DeviceLightController.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "wtf/TemporaryChange.h"
namespace WebCore { namespace WebCore {
...@@ -26,6 +27,17 @@ DeviceLightDispatcher::~DeviceLightDispatcher() ...@@ -26,6 +27,17 @@ DeviceLightDispatcher::~DeviceLightDispatcher()
{ {
} }
void DeviceLightDispatcher::addDeviceLightController(DeviceLightController* controller)
{
addController(controller);
}
void DeviceLightDispatcher::removeDeviceLightController(DeviceLightController* controller)
{
removeController(controller);
}
void DeviceLightDispatcher::startListening() void DeviceLightDispatcher::startListening()
{ {
blink::Platform::current()->setDeviceLightListener(this); blink::Platform::current()->setDeviceLightListener(this);
...@@ -40,7 +52,19 @@ void DeviceLightDispatcher::stopListening() ...@@ -40,7 +52,19 @@ void DeviceLightDispatcher::stopListening()
void DeviceLightDispatcher::didChangeDeviceLight(double value) void DeviceLightDispatcher::didChangeDeviceLight(double value)
{ {
m_lastDeviceLightData = value; m_lastDeviceLightData = value;
notifyControllers();
{
TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
// Don't fire controllers removed or added during event dispatch.
size_t size = m_controllers.size();
for (size_t i = 0; i < size; ++i) {
if (m_controllers[i])
static_cast<DeviceLightController*>(m_controllers[i])->didChangeDeviceLight(m_lastDeviceLightData);
}
}
if (m_needsPurge)
purgeControllers();
} }
double DeviceLightDispatcher::latestDeviceLightData() const double DeviceLightDispatcher::latestDeviceLightData() const
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef DeviceLightDispatcher_h #ifndef DeviceLightDispatcher_h
#define DeviceLightDispatcher_h #define DeviceLightDispatcher_h
#include "core/frame/DeviceEventDispatcherBase.h" #include "core/frame/DeviceSensorEventDispatcher.h"
#include "public/platform/WebDeviceLightListener.h" #include "public/platform/WebDeviceLightListener.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
...@@ -13,21 +13,23 @@ namespace WebCore { ...@@ -13,21 +13,23 @@ namespace WebCore {
class DeviceLightController; class DeviceLightController;
// This class listens to device light data and notifies all registered controllers. // This class listens to device light data and dispatches it to all
class DeviceLightDispatcher FINAL : public DeviceEventDispatcherBase, public blink::WebDeviceLightListener { // listening controllers
class DeviceLightDispatcher FINAL : public DeviceSensorEventDispatcher, public blink::WebDeviceLightListener {
public: public:
static DeviceLightDispatcher& instance(); static DeviceLightDispatcher& instance();
double latestDeviceLightData() const; double latestDeviceLightData() const;
// Inherited from WebDeviceLightListener. // This method is called every time new device light data is available.
virtual void didChangeDeviceLight(double) OVERRIDE; virtual void didChangeDeviceLight(double) OVERRIDE;
void addDeviceLightController(DeviceLightController*);
void removeDeviceLightController(DeviceLightController*);
private: private:
DeviceLightDispatcher(); DeviceLightDispatcher();
virtual ~DeviceLightDispatcher(); virtual ~DeviceLightDispatcher();
// Inherited from DeviceEventDispatcherBase.
virtual void startListening() OVERRIDE; virtual void startListening() OVERRIDE;
virtual void stopListening() OVERRIDE; virtual void stopListening() OVERRIDE;
......
// Copyright 2014 The Chromium Authors. All rights reserved. /*
// Use of this source code is governed by a BSD-style license that can be * Copyright 2010 Apple Inc. All rights reserved.
// found in the LICENSE file. * Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h" #include "config.h"
#include "modules/device_orientation/DeviceMotionController.h" #include "modules/device_orientation/DeviceMotionController.h"
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "modules/EventModules.h" #include "core/frame/DOMWindow.h"
#include "core/page/Page.h"
#include "modules/device_orientation/DeviceMotionData.h" #include "modules/device_orientation/DeviceMotionData.h"
#include "modules/device_orientation/DeviceMotionDispatcher.h" #include "modules/device_orientation/DeviceMotionDispatcher.h"
#include "modules/device_orientation/DeviceMotionEvent.h" #include "modules/device_orientation/DeviceMotionEvent.h"
...@@ -14,7 +37,9 @@ ...@@ -14,7 +37,9 @@
namespace WebCore { namespace WebCore {
DeviceMotionController::DeviceMotionController(Document& document) DeviceMotionController::DeviceMotionController(Document& document)
: DeviceSingleWindowEventController(document) : DeviceSensorEventController(document.page())
, DOMWindowLifecycleObserver(document.domWindow())
, m_document(document)
{ {
} }
...@@ -23,6 +48,11 @@ DeviceMotionController::~DeviceMotionController() ...@@ -23,6 +48,11 @@ DeviceMotionController::~DeviceMotionController()
stopUpdating(); stopUpdating();
} }
void DeviceMotionController::didChangeDeviceMotion(DeviceMotionData* deviceMotionData)
{
dispatchDeviceEvent(DeviceMotionEvent::create(EventTypeNames::devicemotion, deviceMotionData));
}
const char* DeviceMotionController::supplementName() const char* DeviceMotionController::supplementName()
{ {
return "DeviceMotionController"; return "DeviceMotionController";
...@@ -43,30 +73,56 @@ bool DeviceMotionController::hasLastData() ...@@ -43,30 +73,56 @@ bool DeviceMotionController::hasLastData()
return DeviceMotionDispatcher::instance().latestDeviceMotionData(); return DeviceMotionDispatcher::instance().latestDeviceMotionData();
} }
void DeviceMotionController::registerWithDispatcher() PassRefPtrWillBeRawPtr<Event> DeviceMotionController::getLastEvent()
{ {
DeviceMotionDispatcher::instance().addController(this); return DeviceMotionEvent::create(EventTypeNames::devicemotion, DeviceMotionDispatcher::instance().latestDeviceMotionData());
} }
void DeviceMotionController::unregisterWithDispatcher() void DeviceMotionController::registerWithDispatcher()
{ {
DeviceMotionDispatcher::instance().removeController(this); DeviceMotionDispatcher::instance().addDeviceMotionController(this);
} }
PassRefPtrWillBeRawPtr<Event> DeviceMotionController::lastEvent() const void DeviceMotionController::unregisterWithDispatcher()
{ {
return DeviceMotionEvent::create(EventTypeNames::devicemotion, DeviceMotionDispatcher::instance().latestDeviceMotionData()); DeviceMotionDispatcher::instance().removeDeviceMotionController(this);
} }
bool DeviceMotionController::isNullEvent(Event* event) const bool DeviceMotionController::isNullEvent(Event* event)
{ {
DeviceMotionEvent* motionEvent = toDeviceMotionEvent(event); DeviceMotionEvent* motionEvent = toDeviceMotionEvent(event);
return !motionEvent->deviceMotionData()->canProvideEventData(); return !motionEvent->deviceMotionData()->canProvideEventData();
} }
const AtomicString& DeviceMotionController::eventTypeName() const Document* DeviceMotionController::document()
{
return &m_document;
}
void DeviceMotionController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
{ {
return EventTypeNames::devicemotion; if (eventType != EventTypeNames::devicemotion)
return;
if (page() && page()->visibilityState() == PageVisibilityStateVisible)
startUpdating();
m_hasEventListener = true;
}
void DeviceMotionController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType != EventTypeNames::devicemotion || window->hasEventListeners(EventTypeNames::devicemotion))
return;
stopUpdating();
m_hasEventListener = false;
}
void DeviceMotionController::didRemoveAllEventListeners(DOMWindow*)
{
stopUpdating();
m_hasEventListener = false;
} }
} // namespace WebCore } // namespace WebCore
// Copyright 2014 The Chromium Authors. All rights reserved. /*
// Use of this source code is governed by a BSD-style license that can be * Copyright 2010 Apple Inc. All rights reserved.
// found in the LICENSE file. * Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DeviceMotionController_h #ifndef DeviceMotionController_h
#define DeviceMotionController_h #define DeviceMotionController_h
#include "core/dom/DocumentSupplementable.h" #include "core/dom/DocumentSupplementable.h"
#include "core/frame/DeviceSingleWindowEventController.h" #include "core/frame/DOMWindowLifecycleObserver.h"
#include "core/frame/DeviceSensorEventController.h"
#include "modules/EventModules.h"
namespace WebCore { namespace WebCore {
class DeviceMotionData; class DeviceMotionData;
class Event; class DOMWindow;
class DeviceMotionController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceMotionController>, public DeviceSingleWindowEventController, public DocumentSupplement { class DeviceMotionController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceMotionController>, public DeviceSensorEventController, public DocumentSupplement, public DOMWindowLifecycleObserver {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionController); WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionController);
public: public:
virtual ~DeviceMotionController(); virtual ~DeviceMotionController();
...@@ -21,18 +45,24 @@ public: ...@@ -21,18 +45,24 @@ public:
static const char* supplementName(); static const char* supplementName();
static DeviceMotionController& from(Document&); static DeviceMotionController& from(Document&);
void didChangeDeviceMotion(DeviceMotionData*);
private: private:
explicit DeviceMotionController(Document&); explicit DeviceMotionController(Document&);
// Inherited from DeviceEventControllerBase.
virtual void registerWithDispatcher() OVERRIDE; virtual void registerWithDispatcher() OVERRIDE;
virtual void unregisterWithDispatcher() OVERRIDE; virtual void unregisterWithDispatcher() OVERRIDE;
// Inherited from DOMWindowLifecycleObserver.
virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
virtual bool hasLastData() OVERRIDE; virtual bool hasLastData() OVERRIDE;
virtual PassRefPtrWillBeRawPtr<Event> getLastEvent() OVERRIDE;
virtual bool isNullEvent(Event*) OVERRIDE;
virtual Document* document() OVERRIDE;
// Inherited from DeviceSingleWindowEventController. Document& m_document;
virtual PassRefPtrWillBeRawPtr<Event> lastEvent() const OVERRIDE;
virtual const AtomicString& eventTypeName() const OVERRIDE;
virtual bool isNullEvent(Event*) const OVERRIDE;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "modules/device_orientation/DeviceMotionController.h" #include "modules/device_orientation/DeviceMotionController.h"
#include "modules/device_orientation/DeviceMotionData.h" #include "modules/device_orientation/DeviceMotionData.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "wtf/TemporaryChange.h"
namespace WebCore { namespace WebCore {
...@@ -51,6 +52,16 @@ DeviceMotionDispatcher::~DeviceMotionDispatcher() ...@@ -51,6 +52,16 @@ DeviceMotionDispatcher::~DeviceMotionDispatcher()
{ {
} }
void DeviceMotionDispatcher::addDeviceMotionController(DeviceMotionController* controller)
{
addController(controller);
}
void DeviceMotionDispatcher::removeDeviceMotionController(DeviceMotionController* controller)
{
removeController(controller);
}
void DeviceMotionDispatcher::startListening() void DeviceMotionDispatcher::startListening()
{ {
blink::Platform::current()->setDeviceMotionListener(this); blink::Platform::current()->setDeviceMotionListener(this);
...@@ -65,7 +76,19 @@ void DeviceMotionDispatcher::stopListening() ...@@ -65,7 +76,19 @@ void DeviceMotionDispatcher::stopListening()
void DeviceMotionDispatcher::didChangeDeviceMotion(const blink::WebDeviceMotionData& motion) void DeviceMotionDispatcher::didChangeDeviceMotion(const blink::WebDeviceMotionData& motion)
{ {
m_lastDeviceMotionData = DeviceMotionData::create(motion); m_lastDeviceMotionData = DeviceMotionData::create(motion);
notifyControllers();
{
TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
// Don't fire controllers removed or added during event dispatch.
size_t size = m_controllers.size();
for (size_t i = 0; i < size; ++i) {
if (m_controllers[i])
static_cast<DeviceMotionController*>(m_controllers[i])->didChangeDeviceMotion(m_lastDeviceMotionData.get());
}
}
if (m_needsPurge)
purgeControllers();
} }
DeviceMotionData* DeviceMotionDispatcher::latestDeviceMotionData() DeviceMotionData* DeviceMotionDispatcher::latestDeviceMotionData()
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#ifndef DeviceMotionDispatcher_h #ifndef DeviceMotionDispatcher_h
#define DeviceMotionDispatcher_h #define DeviceMotionDispatcher_h
#include "core/frame/DeviceEventDispatcherBase.h" #include "core/frame/DeviceSensorEventDispatcher.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "public/platform/WebDeviceMotionListener.h" #include "public/platform/WebDeviceMotionListener.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
...@@ -45,8 +45,9 @@ namespace WebCore { ...@@ -45,8 +45,9 @@ namespace WebCore {
class DeviceMotionController; class DeviceMotionController;
class DeviceMotionData; class DeviceMotionData;
// This class listens to device motion data and notifies all registered controllers. // This class listens to device motion data and dispatches it to all
class DeviceMotionDispatcher FINAL : public DeviceEventDispatcherBase, public blink::WebDeviceMotionListener { // listening controllers.
class DeviceMotionDispatcher FINAL : public DeviceSensorEventDispatcher, public blink::WebDeviceMotionListener {
public: public:
static DeviceMotionDispatcher& instance(); static DeviceMotionDispatcher& instance();
...@@ -54,14 +55,15 @@ public: ...@@ -54,14 +55,15 @@ public:
// FIXME: make the return value const, see crbug.com/233174. // FIXME: make the return value const, see crbug.com/233174.
DeviceMotionData* latestDeviceMotionData(); DeviceMotionData* latestDeviceMotionData();
// Inherited from WebDeviceMotionListener. // This method is called every time new device motion data is available.
virtual void didChangeDeviceMotion(const blink::WebDeviceMotionData&) OVERRIDE; virtual void didChangeDeviceMotion(const blink::WebDeviceMotionData&) OVERRIDE;
void addDeviceMotionController(DeviceMotionController*);
void removeDeviceMotionController(DeviceMotionController*);
private: private:
DeviceMotionDispatcher(); DeviceMotionDispatcher();
virtual ~DeviceMotionDispatcher(); virtual ~DeviceMotionDispatcher();
// Inherited from DeviceEventDispatcherBase.
virtual void startListening() OVERRIDE; virtual void startListening() OVERRIDE;
virtual void stopListening() OVERRIDE; virtual void stopListening() OVERRIDE;
......
// Copyright 2014 The Chromium Authors. All rights reserved. /*
// Use of this source code is governed by a BSD-style license that can be * Copyright 2010 Apple Inc. All rights reserved.
// found in the LICENSE file. * Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h" #include "config.h"
#include "modules/device_orientation/DeviceOrientationController.h" #include "modules/device_orientation/DeviceOrientationController.h"
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "modules/EventModules.h" #include "core/frame/DOMWindow.h"
#include "core/page/Page.h"
#include "modules/device_orientation/DeviceOrientationData.h" #include "modules/device_orientation/DeviceOrientationData.h"
#include "modules/device_orientation/DeviceOrientationDispatcher.h" #include "modules/device_orientation/DeviceOrientationDispatcher.h"
#include "modules/device_orientation/DeviceOrientationEvent.h" #include "modules/device_orientation/DeviceOrientationEvent.h"
...@@ -14,7 +37,9 @@ ...@@ -14,7 +37,9 @@
namespace WebCore { namespace WebCore {
DeviceOrientationController::DeviceOrientationController(Document& document) DeviceOrientationController::DeviceOrientationController(Document& document)
: DeviceSingleWindowEventController(document) : DeviceSensorEventController(document.page())
, DOMWindowLifecycleObserver(document.domWindow())
, m_document(document)
{ {
} }
...@@ -23,11 +48,11 @@ DeviceOrientationController::~DeviceOrientationController() ...@@ -23,11 +48,11 @@ DeviceOrientationController::~DeviceOrientationController()
stopUpdating(); stopUpdating();
} }
void DeviceOrientationController::didUpdateData() void DeviceOrientationController::didChangeDeviceOrientation(DeviceOrientationData* deviceOrientationData)
{ {
if (m_overrideOrientationData) if (m_overrideOrientationData)
return; return;
dispatchDeviceEvent(lastEvent()); dispatchDeviceEvent(DeviceOrientationEvent::create(EventTypeNames::deviceorientation, deviceOrientationData));
} }
const char* DeviceOrientationController::supplementName() const char* DeviceOrientationController::supplementName()
...@@ -45,7 +70,7 @@ DeviceOrientationController& DeviceOrientationController::from(Document& documen ...@@ -45,7 +70,7 @@ DeviceOrientationController& DeviceOrientationController::from(Document& documen
return *controller; return *controller;
} }
DeviceOrientationData* DeviceOrientationController::lastData() const DeviceOrientationData* DeviceOrientationController::lastData()
{ {
return m_overrideOrientationData ? m_overrideOrientationData.get() : DeviceOrientationDispatcher::instance().latestDeviceOrientationData(); return m_overrideOrientationData ? m_overrideOrientationData.get() : DeviceOrientationDispatcher::instance().latestDeviceOrientationData();
} }
...@@ -55,37 +80,63 @@ bool DeviceOrientationController::hasLastData() ...@@ -55,37 +80,63 @@ bool DeviceOrientationController::hasLastData()
return lastData(); return lastData();
} }
void DeviceOrientationController::registerWithDispatcher() PassRefPtrWillBeRawPtr<Event> DeviceOrientationController::getLastEvent()
{ {
DeviceOrientationDispatcher::instance().addController(this); return DeviceOrientationEvent::create(EventTypeNames::deviceorientation, lastData());
} }
void DeviceOrientationController::unregisterWithDispatcher() void DeviceOrientationController::registerWithDispatcher()
{ {
DeviceOrientationDispatcher::instance().removeController(this); DeviceOrientationDispatcher::instance().addDeviceOrientationController(this);
} }
PassRefPtrWillBeRawPtr<Event> DeviceOrientationController::lastEvent() const void DeviceOrientationController::unregisterWithDispatcher()
{ {
return DeviceOrientationEvent::create(eventTypeName(), lastData()); DeviceOrientationDispatcher::instance().removeDeviceOrientationController(this);
} }
bool DeviceOrientationController::isNullEvent(Event* event) const bool DeviceOrientationController::isNullEvent(Event* event)
{ {
DeviceOrientationEvent* orientationEvent = toDeviceOrientationEvent(event); DeviceOrientationEvent* orientationEvent = toDeviceOrientationEvent(event);
return !orientationEvent->orientation()->canProvideEventData(); return !orientationEvent->orientation()->canProvideEventData();
} }
const AtomicString& DeviceOrientationController::eventTypeName() const Document* DeviceOrientationController::document()
{ {
return EventTypeNames::deviceorientation; return &m_document;
}
void DeviceOrientationController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType != EventTypeNames::deviceorientation)
return;
if (page() && page()->visibilityState() == PageVisibilityStateVisible)
startUpdating();
m_hasEventListener = true;
}
void DeviceOrientationController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
{
if (eventType != EventTypeNames::deviceorientation || window->hasEventListeners(EventTypeNames::deviceorientation))
return;
stopUpdating();
m_hasEventListener = false;
}
void DeviceOrientationController::didRemoveAllEventListeners(DOMWindow* window)
{
stopUpdating();
m_hasEventListener = false;
} }
void DeviceOrientationController::setOverride(DeviceOrientationData* deviceOrientationData) void DeviceOrientationController::setOverride(DeviceOrientationData* deviceOrientationData)
{ {
ASSERT(deviceOrientationData); m_overrideOrientationData.clear();
didChangeDeviceOrientation(deviceOrientationData);
m_overrideOrientationData = deviceOrientationData; m_overrideOrientationData = deviceOrientationData;
dispatchDeviceEvent(lastEvent());
} }
void DeviceOrientationController::clearOverride() void DeviceOrientationController::clearOverride()
...@@ -93,8 +144,9 @@ void DeviceOrientationController::clearOverride() ...@@ -93,8 +144,9 @@ void DeviceOrientationController::clearOverride()
if (!m_overrideOrientationData) if (!m_overrideOrientationData)
return; return;
m_overrideOrientationData.clear(); m_overrideOrientationData.clear();
if (lastData()) DeviceOrientationData* orientation = lastData();
didUpdateData(); if (orientation)
didChangeDeviceOrientation(orientation);
} }
void DeviceOrientationController::trace(Visitor* visitor) void DeviceOrientationController::trace(Visitor* visitor)
......
// Copyright 2014 The Chromium Authors. All rights reserved. /*
// Use of this source code is governed by a BSD-style license that can be * Copyright 2010 Apple Inc. All rights reserved.
// found in the LICENSE file. * Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DeviceOrientationController_h #ifndef DeviceOrientationController_h
#define DeviceOrientationController_h #define DeviceOrientationController_h
#include "core/dom/DocumentSupplementable.h" #include "core/dom/DocumentSupplementable.h"
#include "core/frame/DeviceSingleWindowEventController.h" #include "core/frame/DOMWindowLifecycleObserver.h"
#include "core/frame/DeviceSensorEventController.h"
#include "modules/EventModules.h"
namespace WebCore { namespace WebCore {
class DeviceOrientationData; class DeviceOrientationData;
class Event;
class DeviceOrientationController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceOrientationController>, public DeviceSingleWindowEventController, public DocumentSupplement { class DeviceOrientationController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DeviceOrientationController>, public DeviceSensorEventController, public DocumentSupplement, public DOMWindowLifecycleObserver {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceOrientationController); WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DeviceOrientationController);
public: public:
virtual ~DeviceOrientationController(); virtual ~DeviceOrientationController();
...@@ -21,30 +44,30 @@ public: ...@@ -21,30 +44,30 @@ public:
static const char* supplementName(); static const char* supplementName();
static DeviceOrientationController& from(Document&); static DeviceOrientationController& from(Document&);
// Inherited from DeviceSingleWindowEventController. void didChangeDeviceOrientation(DeviceOrientationData*);
void didUpdateData() OVERRIDE;
void setOverride(DeviceOrientationData*); void setOverride(DeviceOrientationData*);
void clearOverride(); void clearOverride();
// Inherited from DOMWindowLifecycleObserver
virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
virtual void trace(Visitor*) OVERRIDE; virtual void trace(Visitor*) OVERRIDE;
private: private:
explicit DeviceOrientationController(Document&); explicit DeviceOrientationController(Document&);
// Inherited from DeviceEventControllerBase.
virtual void registerWithDispatcher() OVERRIDE; virtual void registerWithDispatcher() OVERRIDE;
virtual void unregisterWithDispatcher() OVERRIDE; virtual void unregisterWithDispatcher() OVERRIDE;
virtual bool hasLastData() OVERRIDE;
// Inherited from DeviceSingleWindowEventController.
virtual PassRefPtrWillBeRawPtr<Event> lastEvent() const OVERRIDE;
virtual const AtomicString& eventTypeName() const OVERRIDE;
virtual bool isNullEvent(Event*) const OVERRIDE;
DeviceOrientationData* lastData() const; DeviceOrientationData* lastData();
virtual bool hasLastData() OVERRIDE;
virtual PassRefPtrWillBeRawPtr<Event> getLastEvent() OVERRIDE;
virtual bool isNullEvent(Event*) OVERRIDE;
virtual Document* document() OVERRIDE;
RefPtrWillBeMember<DeviceOrientationData> m_overrideOrientationData; RefPtrWillBeMember<DeviceOrientationData> m_overrideOrientationData;
Document& m_document;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "modules/device_orientation/DeviceOrientationController.h" #include "modules/device_orientation/DeviceOrientationController.h"
#include "modules/device_orientation/DeviceOrientationData.h" #include "modules/device_orientation/DeviceOrientationData.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "wtf/TemporaryChange.h"
namespace WebCore { namespace WebCore {
...@@ -51,6 +52,16 @@ DeviceOrientationDispatcher::~DeviceOrientationDispatcher() ...@@ -51,6 +52,16 @@ DeviceOrientationDispatcher::~DeviceOrientationDispatcher()
{ {
} }
void DeviceOrientationDispatcher::addDeviceOrientationController(DeviceOrientationController* controller)
{
addController(controller);
}
void DeviceOrientationDispatcher::removeDeviceOrientationController(DeviceOrientationController* controller)
{
removeController(controller);
}
void DeviceOrientationDispatcher::startListening() void DeviceOrientationDispatcher::startListening()
{ {
blink::Platform::current()->setDeviceOrientationListener(this); blink::Platform::current()->setDeviceOrientationListener(this);
...@@ -65,7 +76,19 @@ void DeviceOrientationDispatcher::stopListening() ...@@ -65,7 +76,19 @@ void DeviceOrientationDispatcher::stopListening()
void DeviceOrientationDispatcher::didChangeDeviceOrientation(const blink::WebDeviceOrientationData& motion) void DeviceOrientationDispatcher::didChangeDeviceOrientation(const blink::WebDeviceOrientationData& motion)
{ {
m_lastDeviceOrientationData = DeviceOrientationData::create(motion); m_lastDeviceOrientationData = DeviceOrientationData::create(motion);
notifyControllers();
{
TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
// Don't fire controllers removed or added during event dispatch.
size_t size = m_controllers.size();
for (size_t i = 0; i < size; ++i) {
if (m_controllers[i])
static_cast<DeviceOrientationController*>(m_controllers[i])->didChangeDeviceOrientation(m_lastDeviceOrientationData.get());
}
}
if (m_needsPurge)
purgeControllers();
} }
DeviceOrientationData* DeviceOrientationDispatcher::latestDeviceOrientationData() DeviceOrientationData* DeviceOrientationDispatcher::latestDeviceOrientationData()
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#ifndef DeviceOrientationDispatcher_h #ifndef DeviceOrientationDispatcher_h
#define DeviceOrientationDispatcher_h #define DeviceOrientationDispatcher_h
#include "core/frame/DeviceEventDispatcherBase.h" #include "core/frame/DeviceSensorEventDispatcher.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "public/platform/WebDeviceOrientationListener.h" #include "public/platform/WebDeviceOrientationListener.h"
#include "wtf/RefPtr.h" #include "wtf/RefPtr.h"
...@@ -45,8 +45,9 @@ namespace WebCore { ...@@ -45,8 +45,9 @@ namespace WebCore {
class DeviceOrientationController; class DeviceOrientationController;
class DeviceOrientationData; class DeviceOrientationData;
// This class listens to device orientation data and notifies all registered controllers. // This class listens to device motion data and dispatches it to all
class DeviceOrientationDispatcher : public DeviceEventDispatcherBase, public blink::WebDeviceOrientationListener { // listening controllers.
class DeviceOrientationDispatcher : public DeviceSensorEventDispatcher, public blink::WebDeviceOrientationListener {
public: public:
static DeviceOrientationDispatcher& instance(); static DeviceOrientationDispatcher& instance();
...@@ -54,14 +55,15 @@ public: ...@@ -54,14 +55,15 @@ public:
// FIXME: make the return value const, see crbug.com/233174. // FIXME: make the return value const, see crbug.com/233174.
DeviceOrientationData* latestDeviceOrientationData(); DeviceOrientationData* latestDeviceOrientationData();
// Inherited from WebDeviceOrientationListener. // This method is called every time new device motion data is available.
virtual void didChangeDeviceOrientation(const blink::WebDeviceOrientationData&) OVERRIDE; virtual void didChangeDeviceOrientation(const blink::WebDeviceOrientationData&) OVERRIDE;
void addDeviceOrientationController(DeviceOrientationController*);
void removeDeviceOrientationController(DeviceOrientationController*);
private: private:
DeviceOrientationDispatcher(); DeviceOrientationDispatcher();
~DeviceOrientationDispatcher(); ~DeviceOrientationDispatcher();
// Inherited from DeviceEventDispatcherBase.
virtual void startListening() OVERRIDE; virtual void startListening() OVERRIDE;
virtual void stopListening() OVERRIDE; virtual void stopListening() OVERRIDE;
......
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