1e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block/* 2e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * Copyright 2010, The Android Open Source Project 3e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * 4e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * Redistribution and use in source and binary forms, with or without 5e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * modification, are permitted provided that the following conditions 6e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * are met: 7e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * * Redistributions of source code must retain the above copyright 8e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * notice, this list of conditions and the following disclaimer. 9e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * * Redistributions in binary form must reproduce the above copyright 10e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * notice, this list of conditions and the following disclaimer in the 11e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * documentation and/or other materials provided with the distribution. 12e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * 13e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block */ 25e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 26e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "config.h" 27e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "DeviceOrientationController.h" 28e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 29967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "DeviceOrientation.h" 30e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "DeviceOrientationClient.h" 31e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "DeviceOrientationEvent.h" 32e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 33e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blocknamespace WebCore { 34e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 35e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeDeviceOrientationController::DeviceOrientationController(Page* page, DeviceOrientationClient* client) 36e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block : m_page(page) 37e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block , m_client(client) 380617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen , m_timer(this, &DeviceOrientationController::timerFired) 39e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 40db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block ASSERT(m_client); 41db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block m_client->setController(this); 42e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 43e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 44bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian MonsenDeviceOrientationController::~DeviceOrientationController() 45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{ 46bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen m_client->deviceOrientationControllerDestroyed(); 47bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen} 48bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen 490617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid DeviceOrientationController::timerFired(Timer<DeviceOrientationController>* timer) 500617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 510617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen ASSERT_UNUSED(timer, timer == &m_timer); 52e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block ASSERT(m_client->lastOrientation()); 530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 54e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block RefPtr<DeviceOrientation> orientation = m_client->lastOrientation(); 550617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation.get()); 560617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Vector<RefPtr<DOMWindow> > listenersVector; 580617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen copyToVector(m_newListeners, listenersVector); 590617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen m_newListeners.clear(); 600617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen for (size_t i = 0; i < listenersVector.size(); ++i) 610617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen listenersVector[i]->dispatchEvent(event); 620617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 630617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 64967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid DeviceOrientationController::addListener(DOMWindow* window) 65e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 66e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // If the client already has an orientation, we should fire an event with that 67e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block // orientation. The event is fired asynchronously, but without 680617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // waiting for the client to get a new orientation. 69e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_client->lastOrientation()) { 700617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen m_newListeners.add(window); 710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!m_timer.isActive()) 720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen m_timer.startOneShot(0); 730617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen } 740617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // The client must not call back synchronously. 76967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch bool wasEmpty = m_listeners.isEmpty(); 77967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_listeners.add(window); 78e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (wasEmpty) 79967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_client->startUpdating(); 80967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 81967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 82967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid DeviceOrientationController::removeListener(DOMWindow* window) 83967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 84967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_listeners.remove(window); 850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen m_newListeners.remove(window); 86e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_listeners.isEmpty()) 87967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_client->stopUpdating(); 88967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 89967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 90967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid DeviceOrientationController::removeAllListeners(DOMWindow* window) 91967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 92967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // May be called with a DOMWindow that's not a listener. 93967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!m_listeners.contains(window)) 94967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return; 95967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 96967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_listeners.removeAll(window); 970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen m_newListeners.remove(window); 98e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block if (m_listeners.isEmpty()) 99967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch m_client->stopUpdating(); 100967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 101967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 102967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid DeviceOrientationController::didChangeDeviceOrientation(DeviceOrientation* orientation) 103967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 104967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation); 1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Vector<RefPtr<DOMWindow> > listenersVector; 106967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch copyToVector(m_listeners, listenersVector); 107967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch for (size_t i = 0; i < listenersVector.size(); ++i) 108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch listenersVector[i]->dispatchEvent(event); 109e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 110e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 111e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} // namespace WebCore 112