summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/android')
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp33
-rw-r--r--Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h22
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp96
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h61
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp222
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h86
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp125
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationManager.h80
-rwxr-xr-xSource/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp21
-rw-r--r--Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h11
-rw-r--r--Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp6
-rw-r--r--Source/WebKit/android/jni/GeolocationServiceBridge.cpp242
-rw-r--r--Source/WebKit/android/jni/GeolocationServiceBridge.h75
-rwxr-xr-xSource/WebKit/android/jni/MockGeolocation.cpp67
-rw-r--r--Source/WebKit/android/jni/WebCoreFrameBridge.cpp16
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp39
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h6
17 files changed, 1065 insertions, 143 deletions
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index 907dc3c..cad23dc 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -512,39 +512,6 @@ void ChromeClientAndroid::populateVisitedLinks()
android::WebViewCore::getWebViewCore(view)->populateVisitedLinks(&page->group());
}
-void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
-{
- ASSERT(geolocation);
- if (!m_geolocationPermissions) {
- m_geolocationPermissions = new GeolocationPermissions(android::WebViewCore::getWebViewCore(frame->view()),
- m_webFrame->page()->mainFrame());
- }
- m_geolocationPermissions->queryPermissionState(frame);
-}
-
-void ChromeClientAndroid::cancelGeolocationPermissionRequestForFrame(Frame* frame, WebCore::Geolocation*)
-{
- if (m_geolocationPermissions)
- m_geolocationPermissions->cancelPermissionStateQuery(frame);
-}
-
-void ChromeClientAndroid::provideGeolocationPermissions(const String &origin, bool allow, bool remember)
-{
- ASSERT(m_geolocationPermissions);
- m_geolocationPermissions->providePermissionState(origin, allow, remember);
-}
-
-void ChromeClientAndroid::storeGeolocationPermissions()
-{
- GeolocationPermissions::maybeStorePermanentPermissions();
-}
-
-void ChromeClientAndroid::onMainFrameLoadStarted()
-{
- if (m_geolocationPermissions.get())
- m_geolocationPermissions->resetTemporaryPermissionStates();
-}
-
void ChromeClientAndroid::runOpenPanel(Frame* frame,
PassRefPtr<FileChooser> chooser)
{
diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 36576e6..82f3a23 100644
--- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -28,7 +28,6 @@
#include "ChromeClient.h"
-#include "GeolocationPermissions.h"
#include "PopupMenu.h"
#include "SearchPopupMenu.h"
#include "Timer.h"
@@ -47,13 +46,13 @@ namespace android {
class ChromeClientAndroid : public ChromeClient {
public:
- ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0)
+ ChromeClientAndroid() : m_webFrame(0)
#if USE(ACCELERATED_COMPOSITING)
- , m_rootGraphicsLayer(0)
- , m_needsLayerSync(false)
+ , m_rootGraphicsLayer(0)
+ , m_needsLayerSync(false)
#endif
- , m_triedToReclaimDBQuota(false)
- { }
+ , m_triedToReclaimDBQuota(false)
+ { }
virtual void chromeDestroyed();
virtual void setWindowRect(const FloatRect&);
@@ -147,12 +146,9 @@ namespace android {
#endif
// Methods used to request and provide Geolocation permissions.
- virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
- virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*);
- // Android-specific
- void provideGeolocationPermissions(const String &origin, bool allow, bool remember);
- void storeGeolocationPermissions();
- void onMainFrameLoadStarted();
+ // Not used with client-based Geolocation
+ virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) { ASSERT_NOT_REACHED(); }
+ virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*) { ASSERT_NOT_REACHED(); }
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
virtual void setCursor(const Cursor&);
@@ -202,8 +198,6 @@ namespace android {
private:
android::WebFrame* m_webFrame;
- // The Geolocation permissions manager.
- OwnPtr<GeolocationPermissions> m_geolocationPermissions;
#if USE(ACCELERATED_COMPOSITING)
WebCore::GraphicsLayer* m_rootGraphicsLayer;
bool m_needsLayerSync;
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp
new file mode 100644
index 0000000..7c5b207
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 "GeolocationClientAndroid.h"
+
+#include "WebViewCore.h"
+
+#include <Frame.h>
+#include <Page.h>
+
+using WebCore::Geolocation;
+using WebCore::GeolocationClient;
+using WebCore::GeolocationController;
+using WebCore::GeolocationPosition;
+
+namespace android {
+
+GeolocationClientAndroid::GeolocationClientAndroid() : m_webViewCore(0)
+{
+}
+
+GeolocationClientAndroid::~GeolocationClientAndroid()
+{
+}
+
+void GeolocationClientAndroid::geolocationDestroyed()
+{
+ delete this;
+}
+
+void GeolocationClientAndroid::startUpdating()
+{
+ client()->startUpdating();
+}
+
+void GeolocationClientAndroid::stopUpdating()
+{
+ client()->stopUpdating();
+}
+
+void GeolocationClientAndroid::setEnableHighAccuracy(bool enableHighAccuracy)
+{
+ client()->setEnableHighAccuracy(enableHighAccuracy);
+}
+
+GeolocationPosition* GeolocationClientAndroid::lastPosition()
+{
+ return client()->lastPosition();
+}
+
+void GeolocationClientAndroid::requestPermission(Geolocation* geolocation)
+{
+ client()->requestPermission(geolocation);
+}
+
+void GeolocationClientAndroid::cancelPermissionRequest(Geolocation* geolocation)
+{
+ client()->cancelPermissionRequest(geolocation);
+}
+
+void GeolocationClientAndroid::setWebViewCore(WebViewCore* webViewCore)
+{
+ ASSERT(!m_webViewCore);
+ m_webViewCore = webViewCore;
+ ASSERT(m_webViewCore);
+}
+
+GeolocationClient* GeolocationClientAndroid::client() const
+{
+ return m_webViewCore->geolocationManager()->client();
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h
new file mode 100644
index 0000000..22405e1
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientAndroid.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 GeolocationClientAndroid_h
+#define GeolocationClientAndroid_h
+
+#include <GeolocationClient.h>
+
+namespace android {
+
+class WebViewCore;
+
+// The Android implementation of GeolocationClient. Acts as a proxy to
+// the real or mock impl, which is owned by the GeolocationManager.
+class GeolocationClientAndroid : public WebCore::GeolocationClient {
+public:
+ GeolocationClientAndroid();
+ virtual ~GeolocationClientAndroid();
+
+ // GeolocationClient
+ virtual void geolocationDestroyed();
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual void setEnableHighAccuracy(bool);
+ virtual WebCore::GeolocationPosition* lastPosition();
+ virtual void requestPermission(WebCore::Geolocation*);
+ virtual void cancelPermissionRequest(WebCore::Geolocation*);
+
+ void setWebViewCore(WebViewCore*);
+
+private:
+ WebCore::GeolocationClient* client() const;
+
+ WebViewCore* m_webViewCore;
+};
+
+} // namespace android
+
+#endif // GeolocationClientAndroid_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp
new file mode 100644
index 0000000..4e53d08
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 "GeolocationClientImpl.h"
+
+#include <Frame.h>
+#include <Page.h>
+#include <GeolocationController.h>
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <WebViewCore.h>
+#if PLATFORM(ANDROID)
+// Required for sim-eng build
+#include <math.h>
+#endif
+#include <wtf/CurrentTime.h>
+
+using WebCore::Geolocation;
+using WebCore::GeolocationError;
+using WebCore::GeolocationPosition;
+using WebCore::Timer;
+
+using namespace std;
+
+namespace {
+
+bool isPositionMovement(GeolocationPosition* position1, GeolocationPosition* position2)
+{
+ // For the small distances in which we are likely concerned, it's reasonable
+ // to approximate the distance between the two positions as the sum of the
+ // differences in latitude and longitude.
+ double delta = fabs(position1->latitude() - position2->latitude()) + fabs(position1->longitude() - position2->longitude());
+ // Approximate conversion from degrees of arc to metres.
+ delta *= 60 * 1852;
+ // The threshold is when the distance between the two positions exceeds the
+ // worse (larger) of the two accuracies.
+ int maxAccuracy = max(position1->accuracy(), position2->accuracy());
+ return delta > maxAccuracy;
+}
+
+bool isPositionMoreAccurate(GeolocationPosition* position1, GeolocationPosition* position2)
+{
+ return position2->accuracy() < position1->accuracy();
+}
+
+bool isPositionMoreTimely(GeolocationPosition* position1)
+{
+ double currentTime = WTF::currentTime();
+ double maximumAge = 10 * 60; // 10 minutes
+ return currentTime - position1->timestamp() > maximumAge;
+}
+
+} // anonymous namespace
+
+namespace android {
+
+GeolocationClientImpl::GeolocationClientImpl(WebViewCore* webViewCore)
+ : m_webViewCore(webViewCore)
+ , m_timer(this, &GeolocationClientImpl::timerFired)
+ , m_isSuspended(false)
+ , m_useGps(false)
+{
+}
+
+GeolocationClientImpl::~GeolocationClientImpl()
+{
+}
+
+void GeolocationClientImpl::geolocationDestroyed()
+{
+ // Lifetime is managed by GeolocationManager.
+}
+
+void GeolocationClientImpl::startUpdating()
+{
+ // This method is called every time a new watch or one-shot position request
+ // is started. If we already have a position or an error, call back
+ // immediately.
+ if (m_lastPosition || m_lastError) {
+ m_timer.startOneShot(0);
+ }
+
+ // Lazilly create the Java object.
+ bool haveJavaBridge = m_javaBridge;
+ if (!haveJavaBridge)
+ m_javaBridge.set(new GeolocationServiceBridge(this, m_webViewCore));
+ ASSERT(m_javaBridge);
+
+ // Set whether to use GPS before we start the implementation.
+ m_javaBridge->setEnableGps(m_useGps);
+
+ // If we're suspended, don't start the service. It will be started when we
+ // get the call to resume().
+ if (!haveJavaBridge && !m_isSuspended)
+ m_javaBridge->start();
+}
+
+void GeolocationClientImpl::stopUpdating()
+{
+ // TODO: It would be good to re-use the Java bridge object.
+ m_javaBridge.clear();
+ // Reset last position and error to make sure that we always try to get a
+ // new position from the client when a request is first made.
+ m_lastPosition = 0;
+ m_lastError = 0;
+
+ if (m_timer.isActive())
+ m_timer.stop();
+}
+
+void GeolocationClientImpl::setEnableHighAccuracy(bool enableHighAccuracy)
+{
+ // On Android, high power == GPS.
+ m_useGps = enableHighAccuracy;
+ if (m_javaBridge)
+ m_javaBridge->setEnableGps(m_useGps);
+}
+
+GeolocationPosition* GeolocationClientImpl::lastPosition()
+{
+ return m_lastPosition.get();
+}
+
+void GeolocationClientImpl::requestPermission(Geolocation* geolocation)
+{
+ permissions()->queryPermissionState(geolocation->frame());
+}
+
+void GeolocationClientImpl::cancelPermissionRequest(Geolocation* geolocation)
+{
+ permissions()->cancelPermissionStateQuery(geolocation->frame());
+}
+
+// Note that there is no guarantee that subsequent calls to this method offer a
+// more accurate or updated position.
+void GeolocationClientImpl::newPositionAvailable(PassRefPtr<GeolocationPosition> position)
+{
+ ASSERT(position);
+ if (!m_lastPosition
+ || isPositionMovement(m_lastPosition.get(), position.get())
+ || isPositionMoreAccurate(m_lastPosition.get(), position.get())
+ || isPositionMoreTimely(m_lastPosition.get())) {
+ m_lastPosition = position;
+ // Remove the last error.
+ m_lastError = 0;
+ m_webViewCore->mainFrame()->page()->geolocationController()->positionChanged(m_lastPosition.get());
+ }
+}
+
+void GeolocationClientImpl::newErrorAvailable(PassRefPtr<WebCore::GeolocationError> error)
+{
+ ASSERT(error);
+ // We leave the last position
+ m_lastError = error;
+ m_webViewCore->mainFrame()->page()->geolocationController()->errorOccurred(m_lastError.get());
+}
+
+void GeolocationClientImpl::suspend()
+{
+ m_isSuspended = true;
+ if (m_javaBridge)
+ m_javaBridge->stop();
+}
+
+void GeolocationClientImpl::resume()
+{
+ m_isSuspended = false;
+ if (m_javaBridge)
+ m_javaBridge->start();
+}
+
+void GeolocationClientImpl::resetTemporaryPermissionStates()
+{
+ permissions()->resetTemporaryPermissionStates();
+}
+
+void GeolocationClientImpl::providePermissionState(String origin, bool allow, bool remember)
+{
+ permissions()->providePermissionState(origin, allow, remember);
+}
+
+GeolocationPermissions* GeolocationClientImpl::permissions() const
+{
+ if (!m_permissions)
+ m_permissions = new GeolocationPermissions(m_webViewCore);
+ return m_permissions.get();
+}
+
+void GeolocationClientImpl::timerFired(Timer<GeolocationClientImpl>* timer)
+{
+ ASSERT(&m_timer == timer);
+ ASSERT(m_lastPosition || m_lastError);
+ if (m_lastPosition)
+ m_webViewCore->mainFrame()->page()->geolocationController()->positionChanged(m_lastPosition.get());
+ else
+ m_webViewCore->mainFrame()->page()->geolocationController()->errorOccurred(m_lastError.get());
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h
new file mode 100644
index 0000000..26e6c0c
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 GeolocationClientImpl_h
+#define GeolocationClientImpl_h
+
+#include "GeolocationServiceBridge.h"
+#include "GeolocationClient.h"
+#include "GeolocationPermissions.h"
+
+#include <Timer.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+class Geolocation;
+class GeolocationController;
+}
+
+namespace android {
+
+class WebViewCore;
+
+// The real implementation of GeolocationClient.
+class GeolocationClientImpl : public WebCore::GeolocationClient, public GeolocationServiceBridge::Listener {
+public:
+ GeolocationClientImpl(WebViewCore*);
+ virtual ~GeolocationClientImpl();
+
+ // WebCore::GeolocationClient
+ virtual void geolocationDestroyed();
+ virtual void startUpdating();
+ virtual void stopUpdating();
+ virtual void setEnableHighAccuracy(bool);
+ virtual WebCore::GeolocationPosition* lastPosition();
+ virtual void requestPermission(WebCore::Geolocation*);
+ virtual void cancelPermissionRequest(WebCore::Geolocation*);
+
+ // GeolocationServiceBridge::Listener
+ virtual void newPositionAvailable(PassRefPtr<WebCore::GeolocationPosition>);
+ virtual void newErrorAvailable(PassRefPtr<WebCore::GeolocationError>);
+
+ void suspend();
+ void resume();
+ void resetTemporaryPermissionStates();
+ void providePermissionState(String origin, bool allow, bool remember);
+
+private:
+ GeolocationPermissions* permissions() const;
+ void timerFired(WebCore::Timer<GeolocationClientImpl>*);
+
+ WebViewCore* m_webViewCore;
+ RefPtr<WebCore::GeolocationPosition> m_lastPosition;
+ RefPtr<WebCore::GeolocationError> m_lastError;
+ OwnPtr<GeolocationServiceBridge> m_javaBridge;
+ mutable OwnPtr<GeolocationPermissions> m_permissions;
+ WebCore::Timer<GeolocationClientImpl> m_timer;
+ bool m_isSuspended;
+ bool m_useGps;
+};
+
+} // namespace android
+
+#endif // GeolocationClientImpl_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp
new file mode 100644
index 0000000..cbf399d
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 "GeolocationManager.h"
+
+#include "GeolocationClientImpl.h"
+#include "WebViewCore.h"
+
+#include <Frame.h>
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <JNIHelp.h>
+#include <Page.h>
+
+using WebCore::GeolocationClient;
+using WebCore::GeolocationClientMock;
+
+namespace android {
+
+GeolocationManager::GeolocationManager(WebViewCore* webViewCore)
+ : m_useMock(false)
+ , m_webViewCore(webViewCore)
+{
+}
+
+GeolocationClient* GeolocationManager::client() const
+{
+ if (m_useMock)
+ return mockClient();
+ return realClient();
+}
+
+void GeolocationManager::suspendRealClient()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->suspend();
+}
+
+void GeolocationManager::resumeRealClient()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->resume();
+}
+
+void GeolocationManager::resetRealClientTemporaryPermissionStates()
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->resetTemporaryPermissionStates();
+}
+
+void GeolocationManager::provideRealClientPermissionState(WTF::String origin, bool allow, bool remember)
+{
+ // Don't create the real client if it's not present.
+ if (m_realClient)
+ m_realClient->providePermissionState(origin, allow, remember);
+}
+
+void GeolocationManager::setUseMock()
+{
+ m_useMock = true;
+ m_mockClient.clear();
+}
+
+void GeolocationManager::setMockPosition(PassRefPtr<WebCore::GeolocationPosition> position)
+{
+ ASSERT(m_useMock);
+ mockClient()->setPosition(position);
+}
+
+void GeolocationManager::setMockError(PassRefPtr<WebCore::GeolocationError> error)
+{
+ ASSERT(m_useMock);
+ mockClient()->setError(error);
+}
+
+void GeolocationManager::setMockPermission(bool allowed)
+{
+ ASSERT(m_useMock);
+ mockClient()->setPermission(allowed);
+}
+
+GeolocationClientImpl* GeolocationManager::realClient() const
+{
+ if (!m_realClient)
+ m_realClient.set(new GeolocationClientImpl(m_webViewCore));
+ return m_realClient.get();
+}
+
+GeolocationClientMock* GeolocationManager::mockClient() const
+{
+ ASSERT(m_useMock);
+ if (!m_mockClient) {
+ m_mockClient.set(new GeolocationClientMock);
+ m_mockClient->setController(m_webViewCore->mainFrame()->page()->geolocationController());
+ }
+ return m_mockClient.get();
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationManager.h b/Source/WebKit/android/WebCoreSupport/GeolocationManager.h
new file mode 100644
index 0000000..6459db1
--- /dev/null
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 GeolocationManager_h
+#define GeolocationManager_h
+
+#include "GeolocationClientImpl.h"
+
+#include <GeolocationClientMock.h>
+#include <OwnPtr.h>
+#include <PassRefPtr.h>
+
+namespace WebCore {
+class GeolocationError;
+class GeolocationPosition;
+}
+
+namespace android {
+
+class GeolocationClientImpl;
+class WebViewCore;
+
+// This class takes care of the fact that the client used for Geolocation
+// may be either the real implementation or a mock. It also handles setting the
+// data on the mock client. This class is owned by WebViewCore and exists to
+// keep cruft out of that class.
+class GeolocationManager {
+public:
+ GeolocationManager(WebViewCore*);
+
+ // For use by GeolocationClientAndroid. Gets the current client, either the
+ // real or mock.
+ WebCore::GeolocationClient* client() const;
+
+ void suspendRealClient();
+ void resumeRealClient();
+ void resetRealClientTemporaryPermissionStates();
+ void provideRealClientPermissionState(WTF::String origin, bool allow, bool remember);
+
+ // Sets use of the Geolocation mock client. Also resets that client.
+ void setUseMock();
+ void setMockPosition(PassRefPtr<WebCore::GeolocationPosition>);
+ void setMockError(PassRefPtr<WebCore::GeolocationError>);
+ void setMockPermission(bool allowed);
+
+private:
+ GeolocationClientImpl* realClient() const;
+ WebCore::GeolocationClientMock* mockClient() const;
+
+ bool m_useMock;
+ WebViewCore* m_webViewCore;
+ mutable OwnPtr<GeolocationClientImpl> m_realClient;
+ mutable OwnPtr<WebCore::GeolocationClientMock> m_mockClient;
+};
+
+} // namespace android
+
+#endif // GeolocationManager_h
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
index 36a9b61..fb29bd6 100755
--- a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.cpp
@@ -26,16 +26,16 @@
#include "config.h"
#include "GeolocationPermissions.h"
-#include "DOMWindow.h"
-#include "Frame.h"
-#include "Geolocation.h"
-#include "Navigator.h"
-#include "SQLiteDatabase.h"
-#include "SQLiteFileSystem.h"
-#include "SQLiteStatement.h"
-#include "SQLiteTransaction.h"
#include "WebViewCore.h"
+#include <DOMWindow.h>
+#include <Frame.h>
+#include <Geolocation.h>
+#include <Navigator.h>
+#include <SQLiteDatabase.h>
+#include <SQLiteFileSystem.h>
+#include <SQLiteStatement.h>
+#include <SQLiteTransaction.h>
#include <text/CString.h>
using namespace WebCore;
@@ -51,9 +51,8 @@ String GeolocationPermissions::s_databasePath;
static const char* databaseName = "GeolocationPermissions.db";
-GeolocationPermissions::GeolocationPermissions(WebViewCore* webViewCore, Frame* mainFrame)
+GeolocationPermissions::GeolocationPermissions(WebViewCore* webViewCore)
: m_webViewCore(webViewCore)
- , m_mainFrame(mainFrame)
, m_timer(this, &GeolocationPermissions::timerFired)
{
@@ -266,7 +265,7 @@ void GeolocationPermissions::maybeCallbackFrames(String origin, bool allow)
// or have their contents replaced. Even uniqueChildName is not unique when
// frames are dynamically deleted and created. Instead, we simply call back
// to the Geolocation object in all frames from the correct origin.
- for (Frame* frame = m_mainFrame; frame; frame = frame->tree()->traverseNext()) {
+ for (Frame* frame = m_webViewCore->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
if (origin == frame->document()->securityOrigin()->toString()) {
// If the page has changed, it may no longer have a Geolocation
// object.
diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
index fb31dfe..8f4b96e 100644
--- a/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
+++ b/Source/WebKit/android/WebCoreSupport/GeolocationPermissions.h
@@ -26,9 +26,8 @@
#ifndef GeolocationPermissions_h
#define GeolocationPermissions_h
-#include "PlatformString.h"
-#include "Timer.h"
-
+#include <PlatformString.h>
+#include <Timer.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
@@ -63,9 +62,8 @@ namespace android {
class GeolocationPermissions : public RefCounted<GeolocationPermissions> {
public:
// Creates the GeolocationPermissions object to manage permissions for
- // the specified main frame (i.e. tab). The WebViewCore is used to
- // communicate with the browser to display UI.
- GeolocationPermissions(WebViewCore* webViewCore, WebCore::Frame* mainFrame);
+ // the WebView.
+ GeolocationPermissions(WebViewCore* webViewCore);
virtual ~GeolocationPermissions();
// Queries the permission state for the specified frame. If the
@@ -140,7 +138,6 @@ namespace android {
const WTF::String& nextOriginInQueue();
WebViewCore* m_webViewCore;
- WebCore::Frame* m_mainFrame;
// A vector of the origins queued to make a permission request.
// The first in the vector is the origin currently making the request.
typedef Vector<WTF::String> OriginVector;
diff --git a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
index 9b8aac8..56e7e24 100644
--- a/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
+++ b/Source/WebKit/android/WebCoreSupport/PlatformBridge.cpp
@@ -111,12 +111,6 @@ NPObject* PlatformBridge::pluginScriptableObject(Widget* widget)
return pluginView->getNPObject();
}
-bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView)
-{
- android::WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frameView);
- return webViewCore->isPaused();
-}
-
bool PlatformBridge::popupsAllowed(NPP)
{
return false;
diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.cpp b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp
new file mode 100644
index 0000000..056c788
--- /dev/null
+++ b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 "GeolocationServiceBridge.h"
+
+#include "WebViewCore.h"
+
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include <JNIHelp.h>
+
+using JSC::Bindings::getJNIEnv;
+using WebCore::GeolocationError;
+using WebCore::GeolocationPosition;
+
+namespace android {
+
+static const char* javaGeolocationServiceClassName = "android/webkit/GeolocationService";
+enum javaGeolocationServiceClassMethods {
+ GeolocationServiceMethodInit = 0,
+ GeolocationServiceMethodStart,
+ GeolocationServiceMethodStop,
+ GeolocationServiceMethodSetEnableGps,
+ GeolocationServiceMethodCount,
+};
+static jmethodID javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodCount];
+
+static const JNINativeMethod javaGeolocationServiceClassNativeMethods[] = {
+ { "nativeNewLocationAvailable", "(JLandroid/location/Location;)V",
+ (void*) GeolocationServiceBridge::newLocationAvailable },
+ { "nativeNewErrorAvailable", "(JLjava/lang/String;)V",
+ (void*) GeolocationServiceBridge::newErrorAvailable }
+};
+
+static const char *javaLocationClassName = "android/location/Location";
+enum javaLocationClassMethods {
+ LocationMethodGetLatitude = 0,
+ LocationMethodGetLongitude,
+ LocationMethodHasAltitude,
+ LocationMethodGetAltitude,
+ LocationMethodHasAccuracy,
+ LocationMethodGetAccuracy,
+ LocationMethodHasBearing,
+ LocationMethodGetBearing,
+ LocationMethodHasSpeed,
+ LocationMethodGetSpeed,
+ LocationMethodGetTime,
+ LocationMethodCount,
+};
+static jmethodID javaLocationClassMethodIDs[LocationMethodCount];
+
+GeolocationServiceBridge::GeolocationServiceBridge(Listener* listener, WebViewCore* webViewCore)
+ : m_listener(listener)
+ , m_javaGeolocationServiceObject(0)
+{
+ ASSERT(m_listener);
+ startJavaImplementation(webViewCore);
+}
+
+GeolocationServiceBridge::~GeolocationServiceBridge()
+{
+ stop();
+ stopJavaImplementation();
+}
+
+bool GeolocationServiceBridge::start()
+{
+ if (!m_javaGeolocationServiceObject)
+ return false;
+ return getJNIEnv()->CallBooleanMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart]);
+}
+
+void GeolocationServiceBridge::stop()
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop]);
+}
+
+void GeolocationServiceBridge::setEnableGps(bool enable)
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->CallVoidMethod(m_javaGeolocationServiceObject,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps],
+ enable);
+}
+
+void GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong nativeObject, jobject location)
+{
+ ASSERT(nativeObject);
+ ASSERT(location);
+ GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+ object->m_listener->newPositionAvailable(toGeolocationPosition(env, location));
+}
+
+void GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message)
+{
+ GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject);
+ RefPtr<GeolocationError> error = GeolocationError::create(GeolocationError::PositionUnavailable, jstringToWtfString(env, message));
+ object->m_listener->newErrorAvailable(error.release());
+}
+
+PassRefPtr<GeolocationPosition> GeolocationServiceBridge::toGeolocationPosition(JNIEnv *env, const jobject &location)
+{
+ // Altitude is optional and may not be supplied.
+ bool hasAltitude =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAltitude]);
+ double Altitude =
+ hasAltitude ?
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetAltitude]) :
+ 0.0;
+ // Accuracy is required, but is not supplied by the emulator.
+ double Accuracy =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasAccuracy]) ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetAccuracy]) :
+ 0.0;
+ // heading is optional and may not be supplied.
+ bool hasHeading =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasBearing]);
+ double heading =
+ hasHeading ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetBearing]) :
+ 0.0;
+ // speed is optional and may not be supplied.
+ bool hasSpeed =
+ env->CallBooleanMethod(location, javaLocationClassMethodIDs[LocationMethodHasSpeed]);
+ double speed =
+ hasSpeed ?
+ env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) :
+ 0.0;
+
+ return GeolocationPosition::create(
+ env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]) / 1000.0,
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]),
+ env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]),
+ Accuracy,
+ hasAltitude, Altitude,
+ false, 0.0, // AltitudeAccuracy not provided.
+ hasHeading, heading,
+ hasSpeed, speed);
+}
+
+void GeolocationServiceBridge::startJavaImplementation(WebViewCore* webViewCore)
+{
+ JNIEnv* env = getJNIEnv();
+
+ // Get the Java GeolocationService class.
+ jclass javaGeolocationServiceClass = env->FindClass(javaGeolocationServiceClassName);
+ ASSERT(javaGeolocationServiceClass);
+
+ // Set up the methods we wish to call on the Java GeolocationService class.
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit] =
+ env->GetMethodID(javaGeolocationServiceClass, "<init>", "(Landroid/content/Context;J)V");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStart] =
+ env->GetMethodID(javaGeolocationServiceClass, "start", "()Z");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodStop] =
+ env->GetMethodID(javaGeolocationServiceClass, "stop", "()V");
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodSetEnableGps] =
+ env->GetMethodID(javaGeolocationServiceClass, "setEnableGps", "(Z)V");
+
+ // Create the Java GeolocationService object.
+ jobject context = webViewCore->getContext();
+ if (!context)
+ return;
+ jlong nativeObject = reinterpret_cast<jlong>(this);
+ jobject object = env->NewObject(javaGeolocationServiceClass,
+ javaGeolocationServiceClassMethodIDs[GeolocationServiceMethodInit],
+ context,
+ nativeObject);
+
+ m_javaGeolocationServiceObject = getJNIEnv()->NewGlobalRef(object);
+ ASSERT(m_javaGeolocationServiceObject);
+
+ // Register to handle calls to native methods of the Java GeolocationService
+ // object. We register once only.
+ static int registered = jniRegisterNativeMethods(env,
+ javaGeolocationServiceClassName,
+ javaGeolocationServiceClassNativeMethods,
+ NELEM(javaGeolocationServiceClassNativeMethods));
+ ASSERT(registered == JNI_OK);
+
+ // Set up the methods we wish to call on the Java Location class.
+ jclass javaLocationClass = env->FindClass(javaLocationClassName);
+ ASSERT(javaLocationClass);
+ javaLocationClassMethodIDs[LocationMethodGetLatitude] =
+ env->GetMethodID(javaLocationClass, "getLatitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodGetLongitude] =
+ env->GetMethodID(javaLocationClass, "getLongitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodHasAltitude] =
+ env->GetMethodID(javaLocationClass, "hasAltitude", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetAltitude] =
+ env->GetMethodID(javaLocationClass, "getAltitude", "()D");
+ javaLocationClassMethodIDs[LocationMethodHasAccuracy] =
+ env->GetMethodID(javaLocationClass, "hasAccuracy", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetAccuracy] =
+ env->GetMethodID(javaLocationClass, "getAccuracy", "()F");
+ javaLocationClassMethodIDs[LocationMethodHasBearing] =
+ env->GetMethodID(javaLocationClass, "hasBearing", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetBearing] =
+ env->GetMethodID(javaLocationClass, "getBearing", "()F");
+ javaLocationClassMethodIDs[LocationMethodHasSpeed] =
+ env->GetMethodID(javaLocationClass, "hasSpeed", "()Z");
+ javaLocationClassMethodIDs[LocationMethodGetSpeed] =
+ env->GetMethodID(javaLocationClass, "getSpeed", "()F");
+ javaLocationClassMethodIDs[LocationMethodGetTime] =
+ env->GetMethodID(javaLocationClass, "getTime", "()J");
+}
+
+void GeolocationServiceBridge::stopJavaImplementation()
+{
+ if (!m_javaGeolocationServiceObject)
+ return;
+ getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject);
+}
+
+} // namespace android
diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.h b/Source/WebKit/android/jni/GeolocationServiceBridge.h
new file mode 100644
index 0000000..826ba71
--- /dev/null
+++ b/Source/WebKit/android/jni/GeolocationServiceBridge.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * 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 GeolocationServiceBridge_h
+#define GeolocationServiceBridge_h
+
+#include <JNIUtility.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+class GeolocationError;
+class GeolocationPosition;
+}
+
+namespace android {
+
+class WebViewCore;
+
+// GeolocationServiceBridge is the bridge to the Java implementation. It manages
+// the lifetime of the Java object. It is an implementation detail of
+// GeolocationClientAndroid.
+class GeolocationServiceBridge {
+public:
+ class Listener {
+ public:
+ virtual ~Listener() {}
+ virtual void newPositionAvailable(PassRefPtr<WebCore::GeolocationPosition>) = 0;
+ virtual void newErrorAvailable(PassRefPtr<WebCore::GeolocationError>) = 0;
+ };
+
+ GeolocationServiceBridge(Listener*, WebViewCore*);
+ ~GeolocationServiceBridge();
+
+ bool start();
+ void stop();
+ void setEnableGps(bool enable);
+
+ // Static wrapper functions to hide JNI nastiness.
+ static void newLocationAvailable(JNIEnv *env, jclass, jlong nativeObject, jobject location);
+ static void newErrorAvailable(JNIEnv *env, jclass, jlong nativeObject, jstring message);
+ static PassRefPtr<WebCore::GeolocationPosition> toGeolocationPosition(JNIEnv *env, const jobject &location);
+
+private:
+ void startJavaImplementation(WebViewCore*);
+ void stopJavaImplementation();
+
+ Listener* m_listener;
+ jobject m_javaGeolocationServiceObject;
+};
+
+} // namespace android
+
+#endif // GeolocationServiceBridge_h
diff --git a/Source/WebKit/android/jni/MockGeolocation.cpp b/Source/WebKit/android/jni/MockGeolocation.cpp
index 250953f..164c37d 100755
--- a/Source/WebKit/android/jni/MockGeolocation.cpp
+++ b/Source/WebKit/android/jni/MockGeolocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2009, The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,19 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// The functions in this file are used to configure the mock GeolocationService
+// The functions in this file are used to configure the mock Geolocation client
// for the LayoutTests.
#include "config.h"
-#include "Coordinates.h"
-#include "GeolocationServiceMock.h"
-#include "Geoposition.h"
-#include "JavaSharedClient.h"
-#include "PositionError.h"
-#include "WebCoreJni.h"
-#include <JNIHelp.h>
-#include <JNIUtility.h>
+#include "WebViewCore.h"
+
+#include <GeolocationError.h>
+#include <GeolocationPosition.h>
+#include "ScopedLocalRef.h"
#include <wtf/CurrentTime.h>
using namespace WebCore;
@@ -44,30 +41,46 @@ namespace android {
static const char* javaMockGeolocationClass = "android/webkit/MockGeolocation";
-static void setPosition(JNIEnv* env, jobject, double latitude, double longitude, double accuracy)
+WebViewCore* getWebViewCore(JNIEnv* env, jobject webViewCore)
+{
+ ScopedLocalRef<jclass> webViewCoreClass(env, env->FindClass("android/webkit/WebViewCore"));
+ jfieldID nativeClassField = env->GetFieldID(webViewCoreClass.get(), "mNativeClass", "I");
+ return reinterpret_cast<WebViewCore*>(env->GetIntField(webViewCore, nativeClassField));
+}
+
+static void setUseMock(JNIEnv* env, jobject, jobject webViewCore)
+{
+ getWebViewCore(env, webViewCore)->geolocationManager()->setUseMock();
+}
+
+static void setPosition(JNIEnv* env, jobject, jobject webViewCore, double latitude, double longitude, double accuracy)
+{
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockPosition(GeolocationPosition::create(WTF::currentTime(),
+ latitude,
+ longitude,
+ accuracy,
+ false, 0.0, // altitude,
+ false, 0.0, // altitudeAccuracy,
+ false, 0.0, // heading
+ false, 0.0)); // speed
+}
+
+static void setError(JNIEnv* env, jobject, jobject webViewCore, int code, jstring message)
{
- RefPtr<Coordinates> coordinates = Coordinates::create(latitude,
- longitude,
- false, 0.0, // altitude,
- accuracy,
- false, 0.0, // altitudeAccuracy,
- false, 0.0, // heading
- false, 0.0); // speed
- RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTimeMS());
- GeolocationServiceMock::setPosition(position.release());
+ GeolocationError::ErrorCode codeEnum = static_cast<GeolocationError::ErrorCode>(code);
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockError(GeolocationError::create(codeEnum, jstringToWtfString(env, message)));
}
-static void setError(JNIEnv* env, jobject, int code, jstring message)
+static void setPermission(JNIEnv* env, jobject, jobject webViewCore, bool allow)
{
- PositionError::ErrorCode codeEnum = static_cast<PositionError::ErrorCode>(code);
- String messageString = jstringToWtfString(env, message);
- RefPtr<PositionError> error = PositionError::create(codeEnum, messageString);
- GeolocationServiceMock::setError(error.release());
+ getWebViewCore(env, webViewCore)->geolocationManager()->setMockPermission(allow);
}
static JNINativeMethod gMockGeolocationMethods[] = {
- { "nativeSetPosition", "(DDD)V", (void*) setPosition },
- { "nativeSetError", "(ILjava/lang/String;)V", (void*) setError }
+ { "nativeSetUseMock", "(Landroid/webkit/WebViewCore;)V", (void*) setUseMock },
+ { "nativeSetPosition", "(Landroid/webkit/WebViewCore;DDD)V", (void*) setPosition },
+ { "nativeSetError", "(Landroid/webkit/WebViewCore;ILjava/lang/String;)V", (void*) setError },
+ { "nativeSetPermission", "(Landroid/webkit/WebViewCore;Z)V", (void*) setPermission },
};
int registerMockGeolocation(JNIEnv* env)
diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
index 829c21c..c03c288 100644
--- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -50,6 +50,7 @@
#include "FrameLoadRequest.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "GeolocationClientAndroid.h"
#include "GraphicsContext.h"
#include "HistoryItem.h"
#include "HTMLCollection.h"
@@ -497,15 +498,9 @@ WebFrame::loadStarted(WebCore::Frame* frame)
if (favicon)
env->DeleteLocalRef(favicon);
- // Inform the client that the main frame has started a new load.
- if (isMainFrame && mPage) {
- Chrome* chrome = mPage->chrome();
- if (chrome) {
- ChromeClientAndroid* client = static_cast<ChromeClientAndroid*>(chrome->client());
- if (client)
- client->onMainFrameLoadStarted();
- }
- }
+ // The main frame has started a new load.
+ if (isMainFrame && mPage)
+ WebViewCore::getWebViewCore(mPage->mainFrame()->view())->geolocationManager()->resetRealClientTemporaryPermissionStates();
}
void
@@ -1099,6 +1094,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
EditorClientAndroid* editorC = new EditorClientAndroid;
DeviceMotionClientAndroid* deviceMotionC = new DeviceMotionClientAndroid;
DeviceOrientationClientAndroid* deviceOrientationC = new DeviceOrientationClientAndroid;
+ GeolocationClientAndroid* geolocationC = new GeolocationClientAndroid;
WebCore::Page::PageClients pageClients;
pageClients.chromeClient = chromeC;
@@ -1108,6 +1104,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
pageClients.inspectorClient = new InspectorClientAndroid;
pageClients.deviceMotionClient = deviceMotionC;
pageClients.deviceOrientationClient = deviceOrientationC;
+ pageClients.geolocationClient = geolocationC;
WebCore::Page* page = new WebCore::Page(pageClients);
editorC->setPage(page);
@@ -1150,6 +1147,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
frame->page()->focusController()->setFocused(true);
deviceMotionC->setWebViewCore(webViewCore);
deviceOrientationC->setWebViewCore(webViewCore);
+ geolocationC->setWebViewCore(webViewCore);
// Allow local access to file:/// and substitute data
WebCore::SecurityOrigin::setLocalLoadPolicy(
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 3d86761..1e87b6e 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -436,7 +436,6 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_textWrapWidth(320)
, m_scale(1.0f)
, m_groupForVisitedLinks(0)
- , m_isPaused(false)
, m_cacheMode(0)
, m_fullscreenVideoMode(false)
, m_matchCount(0)
@@ -446,6 +445,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
, m_screenOnCounter(0)
, m_currentNodeDomNavigationAxis(0)
, m_deviceMotionAndOrientationManager(this)
+ , m_geolocationManager(this)
#if ENABLE(TOUCH_EVENTS)
, m_forwardingTouchEvents(false)
#endif
@@ -4764,10 +4764,7 @@ static void GeolocationPermissionsProvide(JNIEnv* env, jobject obj,
jint nativeClass, jstring origin, jboolean allow, jboolean remember)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- Frame* frame = viewImpl->mainFrame();
-
- ChromeClientAndroid* chromeClient = static_cast<ChromeClientAndroid*>(frame->page()->chrome()->client());
- chromeClient->provideGeolocationPermissions(jstringToWtfString(env, origin), allow, remember);
+ viewImpl->geolocationManager()->provideRealClientPermissionState(jstringToWtfString(env, origin), allow, remember);
}
static void RegisterURLSchemeAsLocal(JNIEnv* env, jobject obj, jint nativeClass,
@@ -4781,15 +4778,6 @@ static bool FocusBoundsChanged(JNIEnv* env, jobject obj, jint nativeClass)
return reinterpret_cast<WebViewCore*>(nativeClass)->focusBoundsChanged();
}
-static void SetIsPaused(JNIEnv* env, jobject obj, jint nativeClass,
- jboolean isPaused)
-{
- // tell the webcore thread to stop thinking while we do other work
- // (selection and scrolling). This has nothing to do with the lifecycle
- // pause and resume.
- reinterpret_cast<WebViewCore*>(nativeClass)->setIsPaused(isPaused);
-}
-
static void Pause(JNIEnv* env, jobject obj, jint nativeClass)
{
// This is called for the foreground tab when the browser is put to the
@@ -4797,50 +4785,36 @@ static void Pause(JNIEnv* env, jobject obj, jint nativeClass)
// browser). The browser can only be killed by the system when it is in the
// background, so saving the Geolocation permission state now ensures that
// is maintained when the browser is killed.
- WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- ChromeClient* chromeClient = viewImpl->mainFrame()->page()->chrome()->client();
- ChromeClientAndroid* chromeClientAndroid = static_cast<ChromeClientAndroid*>(chromeClient);
- chromeClientAndroid->storeGeolocationPermissions();
+ GeolocationPermissions::maybeStorePermanentPermissions();
+ WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
Frame* mainFrame = viewImpl->mainFrame();
- for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
- Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation();
- if (geolocation)
- geolocation->suspend();
- }
if (mainFrame)
mainFrame->settings()->setMinDOMTimerInterval(BACKGROUND_TIMER_INTERVAL);
viewImpl->deviceMotionAndOrientationManager()->maybeSuspendClients();
+ viewImpl->geolocationManager()->suspendRealClient();
ANPEvent event;
SkANP::InitEvent(&event, kLifecycle_ANPEventType);
event.data.lifecycle.action = kPause_ANPLifecycleAction;
viewImpl->sendPluginEvent(event);
-
- viewImpl->setIsPaused(true);
}
static void Resume(JNIEnv* env, jobject obj, jint nativeClass)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
Frame* mainFrame = viewImpl->mainFrame();
- for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
- Geolocation* geolocation = frame->domWindow()->navigator()->optionalGeolocation();
- if (geolocation)
- geolocation->resume();
- }
if (mainFrame)
mainFrame->settings()->setMinDOMTimerInterval(FOREGROUND_TIMER_INTERVAL);
viewImpl->deviceMotionAndOrientationManager()->maybeResumeClients();
+ viewImpl->geolocationManager()->resumeRealClient();
ANPEvent event;
SkANP::InitEvent(&event, kLifecycle_ANPEventType);
event.data.lifecycle.action = kResume_ANPLifecycleAction;
viewImpl->sendPluginEvent(event);
-
- viewImpl->setIsPaused(false);
}
static void FreeMemory(JNIEnv* env, jobject obj, jint nativeClass)
@@ -5073,7 +5047,6 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SetNewStorageLimit },
{ "nativeGeolocationPermissionsProvide", "(ILjava/lang/String;ZZ)V",
(void*) GeolocationPermissionsProvide },
- { "nativeSetIsPaused", "(IZ)V", (void*) SetIsPaused },
{ "nativePause", "(I)V", (void*) Pause },
{ "nativeResume", "(I)V", (void*) Resume },
{ "nativeFreeMemory", "(I)V", (void*) FreeMemory },
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index e7e97c3..221b012 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -30,6 +30,7 @@
#include "DOMSelection.h"
#include "FileChooser.h"
#include "FocusDirection.h"
+#include "GeolocationManager.h"
#include "HitTestResult.h"
#include "PicturePile.h"
#include "PlatformGraphicsContext.h"
@@ -546,12 +547,11 @@ namespace android {
void setWebTextViewAutoFillable(int queryId, const string16& previewSummary);
DeviceMotionAndOrientationManager* deviceMotionAndOrientationManager() { return &m_deviceMotionAndOrientationManager; }
+ GeolocationManager* geolocationManager() { return &m_geolocationManager; }
void listBoxRequest(WebCoreReply* reply, const uint16_t** labels,
size_t count, const int enabled[], size_t enabledCount,
bool multiple, const int selected[], size_t selectedCountOrSelection);
- bool isPaused() const { return m_isPaused; }
- void setIsPaused(bool isPaused) { m_isPaused = isPaused; }
bool drawIsPaused() const;
// The actual content (without title bar) size in doc coordinate
int screenWidth() const { return m_screenWidth; }
@@ -782,7 +782,6 @@ namespace android {
int m_textWrapWidth;
float m_scale;
WebCore::PageGroup* m_groupForVisitedLinks;
- bool m_isPaused;
int m_cacheMode;
bool m_fullscreenVideoMode;
@@ -801,6 +800,7 @@ namespace android {
int m_screenOnCounter;
WebCore::Node* m_currentNodeDomNavigationAxis;
DeviceMotionAndOrientationManager m_deviceMotionAndOrientationManager;
+ GeolocationManager m_geolocationManager;
#if ENABLE(TOUCH_EVENTS)
bool m_forwardingTouchEvents;