1/* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "modules/geolocation/GeolocationController.h" 28 29#include "core/inspector/InspectorInstrumentation.h" 30#include "modules/geolocation/GeolocationClient.h" 31#include "modules/geolocation/GeolocationError.h" 32#include "modules/geolocation/GeolocationPosition.h" 33 34namespace WebCore { 35 36GeolocationController::GeolocationController(Page* page, GeolocationClient* client) 37 : m_client(client) 38 , m_page(page) 39{ 40} 41 42GeolocationController::~GeolocationController() 43{ 44 ASSERT(m_observers.isEmpty()); 45 46 if (m_client) 47 m_client->geolocationDestroyed(); 48} 49 50PassOwnPtr<GeolocationController> GeolocationController::create(Page* page, GeolocationClient* client) 51{ 52 return adoptPtr(new GeolocationController(page, client)); 53} 54 55void GeolocationController::addObserver(Geolocation* observer, bool enableHighAccuracy) 56{ 57 // This may be called multiple times with the same observer, though removeObserver() 58 // is called only once with each. 59 bool wasEmpty = m_observers.isEmpty(); 60 m_observers.add(observer); 61 if (enableHighAccuracy) 62 m_highAccuracyObservers.add(observer); 63 64 if (m_client) { 65 if (enableHighAccuracy) 66 m_client->setEnableHighAccuracy(true); 67 if (wasEmpty) 68 m_client->startUpdating(); 69 } 70} 71 72void GeolocationController::removeObserver(Geolocation* observer) 73{ 74 if (!m_observers.contains(observer)) 75 return; 76 77 m_observers.remove(observer); 78 m_highAccuracyObservers.remove(observer); 79 80 if (m_client) { 81 if (m_observers.isEmpty()) 82 m_client->stopUpdating(); 83 else if (m_highAccuracyObservers.isEmpty()) 84 m_client->setEnableHighAccuracy(false); 85 } 86} 87 88void GeolocationController::requestPermission(Geolocation* geolocation) 89{ 90 if (m_client) 91 m_client->requestPermission(geolocation); 92} 93 94void GeolocationController::cancelPermissionRequest(Geolocation* geolocation) 95{ 96 if (m_client) 97 m_client->cancelPermissionRequest(geolocation); 98} 99 100void GeolocationController::positionChanged(GeolocationPosition* position) 101{ 102 position = InspectorInstrumentation::overrideGeolocationPosition(m_page, position); 103 if (!position) { 104 errorOccurred(GeolocationError::create(GeolocationError::PositionUnavailable, "PositionUnavailable").get()); 105 return; 106 } 107 m_lastPosition = position; 108 Vector<RefPtr<Geolocation> > observersVector; 109 copyToVector(m_observers, observersVector); 110 for (size_t i = 0; i < observersVector.size(); ++i) 111 observersVector[i]->positionChanged(); 112} 113 114void GeolocationController::errorOccurred(GeolocationError* error) 115{ 116 Vector<RefPtr<Geolocation> > observersVector; 117 copyToVector(m_observers, observersVector); 118 for (size_t i = 0; i < observersVector.size(); ++i) 119 observersVector[i]->setError(error); 120} 121 122GeolocationPosition* GeolocationController::lastPosition() 123{ 124 if (m_lastPosition.get()) 125 return m_lastPosition.get(); 126 127 if (!m_client) 128 return 0; 129 130 return m_client->lastPosition(); 131} 132 133const char* GeolocationController::supplementName() 134{ 135 return "GeolocationController"; 136} 137 138void provideGeolocationTo(Page* page, GeolocationClient* client) 139{ 140 Supplement<Page>::provideTo(page, GeolocationController::supplementName(), GeolocationController::create(page, client)); 141} 142 143} // namespace WebCore 144