diff options
author | Steve Block <steveblock@google.com> | 2012-05-17 18:17:15 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2012-05-22 14:17:23 +0100 |
commit | 5c36c4ca9214cbbe65d12f6b138aef9618d41a99 (patch) | |
tree | 8112a55f7cf8cb505115429d01ee73badf586896 /Source | |
parent | 0e1334bbc130fb9f7b19ea2354693cea34ebb894 (diff) | |
download | external_webkit-5c36c4ca9214cbbe65d12f6b138aef9618d41a99.zip external_webkit-5c36c4ca9214cbbe65d12f6b138aef9618d41a99.tar.gz external_webkit-5c36c4ca9214cbbe65d12f6b138aef9618d41a99.tar.bz2 |
Switch to client-based Geolocation
The motivation for this switch is that it is required to enable
PREEMPT_GEOLOCATION_PERMISSION. See b/4500947.
The switch involves changing lots of Android's WebKit plumbing to use a new
GeolocationClientAndroid in WebKit (called from
WebCore::GeolocationController), rather than the existing
GeolocationServiceAndroid in WebCore/platform (called from
WebCore::Geolocation). This is complicated by the need to support mocking for
LayoutTests.
The pattern used is very similar to that used for DeviceOrientation and
DeviceMotion. This patch ...
- Enables CLIENT_BASED_GEOLOCATION
- Leaves PREEMPT_GEOLOCATION_PERMISSION disabled for now
- Removes GeolocationServiceAndroid
- Adds a new GeolocationClientAndroid
- Just a proxy to real client
- Adds a new GeolocationManager
- Manages switching between the real and mock clients
- Provides the appropriate client to GeolocationClientAndroid
- Plumbs to the real client calls for permissions and for suspending/resuming
- Adds a new GeolocationClientImpl
- The real client
- Based heavily on GeolocationServiceAndroid
- Delegates to GeolocationServiceBridge, as GeolocationServiceAndroid did
- Calls back directly to GeolocationController
- Owns the existing GeolocationPermissions
- Updates WebViewCore to call the GeolocationManager for permissions and for
suspending/resuming
- Removes superfluous ChromeClient methods for permissions
Note that support for mocking will be added in a later change. See bug for
details.
Bug: 6511338
Change-Id: I4cdbf55846e76b37c161834b83135b4dc48dbcdc
Diffstat (limited to 'Source')
18 files changed, 645 insertions, 373 deletions
diff --git a/Source/JavaScriptCore/wtf/Platform.h b/Source/JavaScriptCore/wtf/Platform.h index a1db9d6..76c2ae4 100644 --- a/Source/JavaScriptCore/wtf/Platform.h +++ b/Source/JavaScriptCore/wtf/Platform.h @@ -726,6 +726,7 @@ #define ENABLE_OFFLINE_WEB_APPLICATIONS 1 #define ENABLE_TOUCH_EVENTS 1 #define ENABLE_GEOLOCATION 1 +#define ENABLE_CLIENT_BASED_GEOLOCATION 1 #define ENABLE_INSPECTOR 0 #define ENABLE_EVENT_SOURCE 0 #define ENABLE_DEVICE_ORIENTATION 1 @@ -1284,8 +1285,13 @@ Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy. pre-emptive permission policy is enabled by default for all client-based implementations. */ #if ENABLE(CLIENT_BASED_GEOLOCATION) +#if PLATFORM(ANDROID) +// Consider enabling preemptive permissions. See b/4500947. +#define WTF_USE_PREEMPT_GEOLOCATION_PERMISSION 0 +#else #define WTF_USE_PREEMPT_GEOLOCATION_PERMISSION 1 #endif +#endif #if CPU(ARM_THUMB2) #define ENABLE_BRANCH_COMPACTION 1 diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 677da4b..6457835 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -496,6 +496,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ page/FrameTree.cpp \ page/FrameView.cpp \ page/Geolocation.cpp \ + page/GeolocationController.cpp \ page/GeolocationPositionCache.cpp \ page/GroupSettings.cpp \ page/History.cpp \ @@ -576,7 +577,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/android/EventLoopAndroid.cpp \ platform/android/FileChooserAndroid.cpp \ platform/android/FileSystemAndroid.cpp \ - platform/android/GeolocationServiceAndroid.cpp \ platform/android/KeyEventAndroid.cpp \ platform/android/LanguageAndroid.cpp \ platform/android/LocalizedStringsAndroid.cpp \ diff --git a/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp b/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp deleted file mode 100644 index 9ea0362..0000000 --- a/Source/WebCore/platform/android/GeolocationServiceAndroid.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2009, 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 "GeolocationServiceAndroid.h" - -#include "Frame.h" -#include "Geolocation.h" -#include "Geoposition.h" -#include "PositionError.h" -#include "PositionOptions.h" - -#include <WebViewCore.h> - -#if PLATFORM(ANDROID) -// Required for sim-eng build -#include <math.h> -#endif -#include <wtf/CurrentTime.h> - -using JSC::Bindings::getJNIEnv; -using android::GeolocationServiceBridge; -using android::WebViewCore; -using namespace std; - -namespace WebCore { - -// GeolocationServiceAndroid is the Android implmentation of Geolocation -// service. Each object of this class owns an object of type -// GeolocationServiceBridge, which in turn owns a Java GeolocationService -// object. Therefore, there is a 1:1 mapping between Geolocation, -// GeolocationServiceAndroid, GeolocationServiceBridge and Java -// GeolocationService objects. In the case where multiple Geolocation objects -// exist simultaneously, the corresponsing Java GeolocationService objects all -// register with the platform location service. It is the platform service that -// handles making sure that updates are passed to all Geolocation objects. -GeolocationService* GeolocationServiceAndroid::create(GeolocationServiceClient* client) -{ - return new GeolocationServiceAndroid(client); -} - -GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceAndroid::create; - -GeolocationServiceAndroid::GeolocationServiceAndroid(GeolocationServiceClient* client) - : GeolocationService(client) - , m_timer(this, &GeolocationServiceAndroid::timerFired) - , m_javaBridge(0) -{ -} - -// ANDROID -// TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082 -bool GeolocationServiceAndroid::startUpdating(PositionOptions* options, bool suspend) -{ - // ANDROID - // This is an ugly hack. A correct fix would require a change to WebCore, - // but this isn't worth the effort as we're in the process of switching to a - // client-based implementation. See https://bugs.webkit.org/show_bug.cgi?id=40373 - Frame* frame = reinterpret_cast<Geolocation*>(geolocationServiceClient())->frame(); - if (!frame) - return false; - - // 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) { - ASSERT(m_javaBridge); - m_timer.startOneShot(0); - } - - // Lazilly create the Java object. - bool haveJavaBridge = m_javaBridge; - if (!haveJavaBridge) - m_javaBridge.set(new GeolocationServiceBridge(this, WebViewCore::getWebViewCore(frame->view()))); - ASSERT(m_javaBridge); - - // On Android, high power == GPS. Set whether to use GPS before we start the - // implementation. - ASSERT(options); - if (options->enableHighAccuracy()) - m_javaBridge->setEnableGps(true); - - // We need only start the service when it's first created. - if (!haveJavaBridge) { - // If the browser is paused, don't start the service. It will be started - // when we get the call to resume. - // ANDROID - // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082 - if (!suspend) - return m_javaBridge->start(); - } - - return true; -} - -void GeolocationServiceAndroid::stopUpdating() -{ - // Called when the Geolocation object has no watches or one shots in - // progress. This may be called repeatedly. - m_javaBridge.clear(); - // Reset last position and error to make sure that we always try to get a - // new position from the system service when a request is first made. - m_lastPosition = 0; - m_lastError = 0; - // remove the pending timer - if (m_timer.isActive()) - m_timer.stop(); -} - -void GeolocationServiceAndroid::suspend() -{ - if (m_javaBridge) - m_javaBridge->stop(); -} - -void GeolocationServiceAndroid::resume() -{ - if (m_javaBridge) - m_javaBridge->start(); -} - -// Note that there is no guarantee that subsequent calls to this method offer a -// more accurate or updated position. -void GeolocationServiceAndroid::newPositionAvailable(PassRefPtr<Geoposition> position) -{ - ASSERT(position); - if (!m_lastPosition - || isPositionMovement(m_lastPosition.get(), position.get()) - || isPositionMoreAccurate(m_lastPosition.get(), position.get()) - || isPositionMoreTimely(m_lastPosition.get(), position.get())) { - m_lastPosition = position; - // Remove the last error. - m_lastError = 0; - positionChanged(); - } -} - -void GeolocationServiceAndroid::newErrorAvailable(PassRefPtr<PositionError> error) -{ - ASSERT(error); - // We leave the last position - m_lastError = error; - errorOccurred(); -} - -void GeolocationServiceAndroid::timerFired(Timer<GeolocationServiceAndroid>* timer) -{ - ASSERT(&m_timer == timer); - ASSERT(m_lastPosition || m_lastError); - if (m_lastPosition) - positionChanged(); - else if (m_lastError) - errorOccurred(); -} - -bool GeolocationServiceAndroid::isPositionMovement(Geoposition* position1, Geoposition* position2) -{ - ASSERT(position1 && 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->coords()->latitude() - position2->coords()->latitude()) - + fabs(position1->coords()->longitude() - position2->coords()->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->coords()->accuracy(), position2->coords()->accuracy()); - return delta > maxAccuracy; -} - -bool GeolocationServiceAndroid::isPositionMoreAccurate(Geoposition* position1, Geoposition* position2) -{ - ASSERT(position1 && position2); - return position2->coords()->accuracy() < position1->coords()->accuracy(); -} - -bool GeolocationServiceAndroid::isPositionMoreTimely(Geoposition* position1, Geoposition* position2) -{ - ASSERT(position1 && position2); - DOMTimeStamp currentTime = convertSecondsToDOMTimeStamp(WTF::currentTime()); - DOMTimeStamp maximumAge = convertSecondsToDOMTimeStamp(10 * 60); // 10 minutes - return currentTime - position1->timestamp() > maximumAge; -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/android/GeolocationServiceAndroid.h b/Source/WebCore/platform/android/GeolocationServiceAndroid.h deleted file mode 100644 index 47c3ffe..0000000 --- a/Source/WebCore/platform/android/GeolocationServiceAndroid.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2009, 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 GeolocationServiceAndroid_h -#define GeolocationServiceAndroid_h - -#include "GeolocationService.h" -#include "Timer.h" - -#include <GeolocationServiceBridge.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> - -namespace WebCore { - -class GeolocationServiceAndroid : public GeolocationService, public android::GeolocationServiceBridge::Listener { -public: - static GeolocationService* create(GeolocationServiceClient*); - - virtual ~GeolocationServiceAndroid() { }; - - // GeolocationService - // ANDROID - // TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082 - virtual bool startUpdating(PositionOptions*, bool suspend); - virtual void stopUpdating(); - virtual Geoposition* lastPosition() const { return m_lastPosition.get(); } - virtual PositionError* lastError() const { return m_lastError.get(); } - virtual void suspend(); - virtual void resume(); - - // android::GeolocationServiceBridge::Listener - virtual void newPositionAvailable(PassRefPtr<Geoposition>); - virtual void newErrorAvailable(PassRefPtr<PositionError>); - - void timerFired(Timer<GeolocationServiceAndroid>* timer); - -private: - GeolocationServiceAndroid(GeolocationServiceClient*); - - static bool isPositionMovement(Geoposition* position1, Geoposition* position2); - static bool isPositionMoreAccurate(Geoposition* position1, Geoposition* position2); - static bool isPositionMoreTimely(Geoposition* position1, Geoposition* position2); - - Timer<GeolocationServiceAndroid> m_timer; - RefPtr<Geoposition> m_lastPosition; - RefPtr<PositionError> m_lastError; - OwnPtr<android::GeolocationServiceBridge> m_javaBridge; -}; - -} // namespace WebCore - -#endif // GeolocationServiceAndroid_h diff --git a/Source/WebKit/Android.mk b/Source/WebKit/Android.mk index a27576b..07634b6 100644 --- a/Source/WebKit/Android.mk +++ b/Source/WebKit/Android.mk @@ -27,6 +27,9 @@ LOCAL_SRC_FILES := \ android/WebCoreSupport/EditorClientAndroid.cpp \ android/WebCoreSupport/FrameLoaderClientAndroid.cpp \ android/WebCoreSupport/FrameNetworkingContextAndroid.cpp \ + android/WebCoreSupport/GeolocationClientAndroid.cpp \ + android/WebCoreSupport/GeolocationClientImpl.cpp \ + android/WebCoreSupport/GeolocationManager.cpp \ android/WebCoreSupport/GeolocationPermissions.cpp \ android/WebCoreSupport/MediaPlayerPrivateAndroid.cpp \ android/WebCoreSupport/MemoryUsage.cpp \ diff --git a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index e736087..cad23dc 100644 --- a/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/Source/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -512,34 +512,6 @@ void ChromeClientAndroid::populateVisitedLinks() android::WebViewCore::getWebViewCore(view)->populateVisitedLinks(&page->group()); } -void ChromeClientAndroid::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) -{ - ASSERT(geolocation); - if (!m_geolocationPermissions) { - WebViewCore* webViewCore = android::WebViewCore::getWebViewCore(frame->view()); - ASSERT(webViewCore->mainFrame() == m_webFrame->page()->mainFrame()); - m_geolocationPermissions = new GeolocationPermissions(webViewCore); - } - 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) -{ - m_geolocationPermissions->providePermissionState(origin, allow, remember); -} - -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 8b509d5..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,11 +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 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&); @@ -201,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..fce0e37 --- /dev/null +++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.cpp @@ -0,0 +1,199 @@ +/* + * 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 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_isSuspended(false) + , m_useGps(false) +{ +} + +GeolocationClientImpl::~GeolocationClientImpl() +{ +} + +void GeolocationClientImpl::geolocationDestroyed() +{ + // Lifetime is managed by GeolocationManager. +} + +void GeolocationClientImpl::startUpdating() +{ + // Lazilly create the Java object. + ASSERT(!m_javaBridge); + 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 (!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; +} + +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(); +} + +} // namespace android diff --git a/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h new file mode 100644 index 0000000..81a6db3 --- /dev/null +++ b/Source/WebKit/android/WebCoreSupport/GeolocationClientImpl.h @@ -0,0 +1,83 @@ +/* + * 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 <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; + + WebViewCore* m_webViewCore; + RefPtr<WebCore::GeolocationPosition> m_lastPosition; + RefPtr<WebCore::GeolocationError> m_lastError; + OwnPtr<GeolocationServiceBridge> m_javaBridge; + mutable OwnPtr<GeolocationPermissions> m_permissions; + 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..8d0d6b5 --- /dev/null +++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.cpp @@ -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. + */ + +#include "config.h" +#include "GeolocationManager.h" + +#include "GeolocationClientImpl.h" +#include "WebViewCore.h" + +#include <GeolocationError.h> +#include <GeolocationPosition.h> +#include <JNIHelp.h> + +using WebCore::GeolocationClient; + +namespace android { + +GeolocationManager::GeolocationManager(WebViewCore* webViewCore) + : m_webViewCore(webViewCore) +{ +} + +GeolocationClient* GeolocationManager::client() const +{ + // TODO: Return the mock client when appropriate. See http://b/6511338. + 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); +} + +GeolocationClientImpl* GeolocationManager::realClient() const +{ + if (!m_realClient) + m_realClient.set(new GeolocationClientImpl(m_webViewCore)); + return m_realClient.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..707cf6f --- /dev/null +++ b/Source/WebKit/android/WebCoreSupport/GeolocationManager.h @@ -0,0 +1,71 @@ +/* + * 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 <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. +// TODO: Add support for mock. See b/6511338. +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); + +private: + GeolocationClientImpl* realClient() const; + + WebViewCore* m_webViewCore; + mutable OwnPtr<GeolocationClientImpl> m_realClient; +}; + +} // namespace android + +#endif // GeolocationManager_h diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.cpp b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp index 044131f..056c788 100644 --- a/Source/WebKit/android/jni/GeolocationServiceBridge.cpp +++ b/Source/WebKit/android/jni/GeolocationServiceBridge.cpp @@ -26,17 +26,15 @@ #include "config.h" #include "GeolocationServiceBridge.h" -#include "GeolocationServiceAndroid.h" #include "WebViewCore.h" -#include <Geoposition.h> +#include <GeolocationError.h> +#include <GeolocationPosition.h> #include <JNIHelp.h> -#include <PositionError.h> using JSC::Bindings::getJNIEnv; -using WebCore::Coordinates; -using WebCore::Geoposition; -using WebCore::PositionError; +using WebCore::GeolocationError; +using WebCore::GeolocationPosition; namespace android { @@ -118,18 +116,17 @@ void GeolocationServiceBridge::newLocationAvailable(JNIEnv* env, jclass, jlong n ASSERT(nativeObject); ASSERT(location); GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject); - object->m_listener->newPositionAvailable(toGeoposition(env, location)); + object->m_listener->newPositionAvailable(toGeolocationPosition(env, location)); } void GeolocationServiceBridge::newErrorAvailable(JNIEnv* env, jclass, jlong nativeObject, jstring message) { GeolocationServiceBridge* object = reinterpret_cast<GeolocationServiceBridge*>(nativeObject); - RefPtr<PositionError> error = - PositionError::create(PositionError::POSITION_UNAVAILABLE, android::jstringToWtfString(env, message)); + RefPtr<GeolocationError> error = GeolocationError::create(GeolocationError::PositionUnavailable, jstringToWtfString(env, message)); object->m_listener->newErrorAvailable(error.release()); } -PassRefPtr<Geoposition> GeolocationServiceBridge::toGeoposition(JNIEnv *env, const jobject &location) +PassRefPtr<GeolocationPosition> GeolocationServiceBridge::toGeolocationPosition(JNIEnv *env, const jobject &location) { // Altitude is optional and may not be supplied. bool hasAltitude = @@ -158,18 +155,15 @@ PassRefPtr<Geoposition> GeolocationServiceBridge::toGeoposition(JNIEnv *env, con env->CallFloatMethod(location, javaLocationClassMethodIDs[LocationMethodGetSpeed]) : 0.0; - RefPtr<Coordinates> newCoordinates = Coordinates::create( + return GeolocationPosition::create( + env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime]) / 1000.0, env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLatitude]), env->CallDoubleMethod(location, javaLocationClassMethodIDs[LocationMethodGetLongitude]), - hasAltitude, Altitude, Accuracy, + hasAltitude, Altitude, false, 0.0, // AltitudeAccuracy not provided. hasHeading, heading, hasSpeed, speed); - - return Geoposition::create( - newCoordinates.release(), - env->CallLongMethod(location, javaLocationClassMethodIDs[LocationMethodGetTime])); } void GeolocationServiceBridge::startJavaImplementation(WebViewCore* webViewCore) @@ -240,10 +234,9 @@ void GeolocationServiceBridge::startJavaImplementation(WebViewCore* webViewCore) void GeolocationServiceBridge::stopJavaImplementation() { - // Called by GeolocationServiceAndroid on WebKit thread. if (!m_javaGeolocationServiceObject) return; getJNIEnv()->DeleteGlobalRef(m_javaGeolocationServiceObject); } -} // namespace WebCore +} // namespace android diff --git a/Source/WebKit/android/jni/GeolocationServiceBridge.h b/Source/WebKit/android/jni/GeolocationServiceBridge.h index 1813984..826ba71 100644 --- a/Source/WebKit/android/jni/GeolocationServiceBridge.h +++ b/Source/WebKit/android/jni/GeolocationServiceBridge.h @@ -30,8 +30,8 @@ #include <wtf/PassRefPtr.h> namespace WebCore { -class Geoposition; -class PositionError; +class GeolocationError; +class GeolocationPosition; } namespace android { @@ -40,14 +40,14 @@ class WebViewCore; // GeolocationServiceBridge is the bridge to the Java implementation. It manages // the lifetime of the Java object. It is an implementation detail of -// GeolocationServiceAndroid. +// GeolocationClientAndroid. class GeolocationServiceBridge { public: class Listener { public: virtual ~Listener() {} - virtual void newPositionAvailable(PassRefPtr<WebCore::Geoposition>) = 0; - virtual void newErrorAvailable(PassRefPtr<WebCore::PositionError>) = 0; + virtual void newPositionAvailable(PassRefPtr<WebCore::GeolocationPosition>) = 0; + virtual void newErrorAvailable(PassRefPtr<WebCore::GeolocationError>) = 0; }; GeolocationServiceBridge(Listener*, WebViewCore*); @@ -60,7 +60,7 @@ public: // 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::Geoposition> toGeoposition(JNIEnv *env, const jobject &location); + static PassRefPtr<WebCore::GeolocationPosition> toGeolocationPosition(JNIEnv *env, const jobject &location); private: void startJavaImplementation(WebViewCore*); diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp index af582fa..a9fa288 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 8499b50..60830fc 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -443,6 +443,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 @@ -4751,10 +4752,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, @@ -4788,15 +4786,11 @@ static void Pause(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->suspend(); - } if (mainFrame) mainFrame->settings()->setMinDOMTimerInterval(BACKGROUND_TIMER_INTERVAL); viewImpl->deviceMotionAndOrientationManager()->maybeSuspendClients(); + viewImpl->geolocationManager()->suspendRealClient(); ANPEvent event; SkANP::InitEvent(&event, kLifecycle_ANPEventType); @@ -4810,15 +4804,11 @@ 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); diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index bfd9387..f371f69 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" @@ -543,6 +544,7 @@ 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, @@ -798,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; |