1/*
2 * Copyright (C) 2011, 2012, 2013 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 "WebGeolocationManagerProxy.h"
28
29#include "APIGeolocationProvider.h"
30#include "WebGeolocationManagerMessages.h"
31#include "WebGeolocationManagerProxyMessages.h"
32#include "WebGeolocationPosition.h"
33#include "WebProcessPool.h"
34
35namespace WebKit {
36
37const char* WebGeolocationManagerProxy::supplementName()
38{
39 return "WebGeolocationManagerProxy";
40}
41
42Ref<WebGeolocationManagerProxy> WebGeolocationManagerProxy::create(WebProcessPool* processPool)
43{
44 return adoptRef(*new WebGeolocationManagerProxy(processPool));
45}
46
47WebGeolocationManagerProxy::WebGeolocationManagerProxy(WebProcessPool* processPool)
48 : WebContextSupplement(processPool)
49 , m_provider(std::make_unique<API::GeolocationProvider>())
50{
51 WebContextSupplement::processPool()->addMessageReceiver(Messages::WebGeolocationManagerProxy::messageReceiverName(), *this);
52}
53
54void WebGeolocationManagerProxy::setProvider(std::unique_ptr<API::GeolocationProvider>&& provider)
55{
56 if (!provider)
57 m_provider = std::make_unique<API::GeolocationProvider>();
58 else
59 m_provider = WTFMove(provider);
60}
61
62// WebContextSupplement
63
64void WebGeolocationManagerProxy::processPoolDestroyed()
65{
66 bool wasUpdating = isUpdating();
67 m_updateRequesters.clear();
68
69 ASSERT(!isUpdating());
70 if (wasUpdating)
71 m_provider->stopUpdating(*this);
72}
73
74void WebGeolocationManagerProxy::processDidClose(WebProcessProxy* webProcessProxy)
75{
76 removeRequester(webProcessProxy);
77}
78
79void WebGeolocationManagerProxy::refWebContextSupplement()
80{
81 API::Object::ref();
82}
83
84void WebGeolocationManagerProxy::derefWebContextSupplement()
85{
86 API::Object::deref();
87}
88
89void WebGeolocationManagerProxy::providerDidChangePosition(WebGeolocationPosition* position)
90{
91 m_lastPosition = position->corePosition();
92
93 if (!processPool())
94 return;
95
96 processPool()->sendToAllProcesses(Messages::WebGeolocationManager::DidChangePosition(m_lastPosition.value()));
97}
98
99void WebGeolocationManagerProxy::providerDidFailToDeterminePosition(const String& errorMessage)
100{
101 if (!processPool())
102 return;
103
104 processPool()->sendToAllProcesses(Messages::WebGeolocationManager::DidFailToDeterminePosition(errorMessage));
105}
106
107#if PLATFORM(IOS_FAMILY)
108void WebGeolocationManagerProxy::resetPermissions()
109{
110 processPool()->sendToAllProcesses(Messages::WebGeolocationManager::ResetPermissions());
111}
112#endif
113
114void WebGeolocationManagerProxy::startUpdating(IPC::Connection& connection)
115{
116 bool wasUpdating = isUpdating();
117 m_updateRequesters.add(&connection.client());
118 if (!wasUpdating) {
119 m_provider->setEnableHighAccuracy(*this, isHighAccuracyEnabled());
120 m_provider->startUpdating(*this);
121 } else if (m_lastPosition)
122 connection.send(Messages::WebGeolocationManager::DidChangePosition(m_lastPosition.value()), 0);
123}
124
125void WebGeolocationManagerProxy::stopUpdating(IPC::Connection& connection)
126{
127 removeRequester(&connection.client());
128}
129
130void WebGeolocationManagerProxy::removeRequester(const IPC::Connection::Client* client)
131{
132 bool wasUpdating = isUpdating();
133 bool highAccuracyWasEnabled = isHighAccuracyEnabled();
134
135 m_highAccuracyRequesters.remove(client);
136 m_updateRequesters.remove(client);
137
138 if (wasUpdating && !isUpdating())
139 m_provider->stopUpdating(*this);
140 else {
141 bool highAccuracyShouldBeEnabled = isHighAccuracyEnabled();
142 if (highAccuracyShouldBeEnabled != highAccuracyWasEnabled)
143 m_provider->setEnableHighAccuracy(*this, highAccuracyShouldBeEnabled);
144 }
145}
146
147void WebGeolocationManagerProxy::setEnableHighAccuracy(IPC::Connection& connection, bool enabled)
148{
149 bool highAccuracyWasEnabled = isHighAccuracyEnabled();
150
151 if (enabled)
152 m_highAccuracyRequesters.add(&connection.client());
153 else
154 m_highAccuracyRequesters.remove(&connection.client());
155
156 bool highAccuracyShouldBeEnabled = isHighAccuracyEnabled();
157 if (isUpdating() && highAccuracyWasEnabled != highAccuracyShouldBeEnabled)
158 m_provider->setEnableHighAccuracy(*this, highAccuracyShouldBeEnabled);
159}
160
161} // namespace WebKit
162