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 34 namespace WebCore { 35 36 GeolocationController::GeolocationController(Page* page, GeolocationClient* client) 37 : m_client(client) 38 , m_page(page) 39 { 40 } 41 42 GeolocationController::~GeolocationController() 43 { 44 ASSERT(m_observers.isEmpty()); 45 46 if (m_client) 47 m_client->geolocationDestroyed(); 48 } 49 50 PassOwnPtr<GeolocationController> GeolocationController::create(Page* page, GeolocationClient* client) 51 { 52 return adoptPtr(new GeolocationController(page, client)); 53 } 54 55 void 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 72 void 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 88 void GeolocationController::requestPermission(Geolocation* geolocation) 89 { 90 if (m_client) 91 m_client->requestPermission(geolocation); 92 } 93 94 void GeolocationController::cancelPermissionRequest(Geolocation* geolocation) 95 { 96 if (m_client) 97 m_client->cancelPermissionRequest(geolocation); 98 } 99 100 void 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 114 void 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 122 GeolocationPosition* 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 133 const char* GeolocationController::supplementName() 134 { 135 return "GeolocationController"; 136 } 137 138 void provideGeolocationTo(Page* page, GeolocationClient* client) 139 { 140 Supplement<Page>::provideTo(page, GeolocationController::supplementName(), GeolocationController::create(page, client)); 141 } 142 143 } // namespace WebCore 144