diff options
author | jknotten@chromium.org <jknotten@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-14 17:45:50 +0000 |
---|---|---|
committer | jknotten@chromium.org <jknotten@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-14 17:45:50 +0000 |
commit | ffd0abdc00f3c8e8e711d86c8633976db3963f42 (patch) | |
tree | 0f8e55a221d3eaa3f18af47b61dae31c078890b3 /chrome/renderer | |
parent | 52dd1112a84d627fa45b7c5051f14b5b118f5a83 (diff) | |
download | chromium_src-ffd0abdc00f3c8e8e711d86c8633976db3963f42.zip chromium_src-ffd0abdc00f3c8e8e711d86c8633976db3963f42.tar.gz chromium_src-ffd0abdc00f3c8e8e711d86c8633976db3963f42.tar.bz2 |
Client-based geolocation support.
Add in support for client-based geolocation in WebKit.
Default to disabled (ENABLE_CLIENT_BASED_GEOLOCATION=0) in features_override.gypi
until all the WebKit patches (see https://bugs.webkit.org/show_bug.cgi?id=45752)
have landed. When we switch over to client-based geolocation, we should remove
the old non-client-based geolocation code.
BUG=55907
Review URL: http://codereview.chromium.org/5612005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69156 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/geolocation_dispatcher.cc | 155 | ||||
-rw-r--r-- | chrome/renderer/geolocation_dispatcher.h | 75 | ||||
-rw-r--r-- | chrome/renderer/geolocation_dispatcher_old.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/geolocation_dispatcher_old.h | 8 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 10 |
6 files changed, 261 insertions, 3 deletions
diff --git a/chrome/renderer/geolocation_dispatcher.cc b/chrome/renderer/geolocation_dispatcher.cc new file mode 100644 index 0000000..39596af --- /dev/null +++ b/chrome/renderer/geolocation_dispatcher.cc @@ -0,0 +1,155 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#if defined(ENABLE_CLIENT_BASED_GEOLOCATION) + +#include "chrome/renderer/geolocation_dispatcher.h" + +#include "chrome/renderer/render_view.h" +#include "ipc/ipc_message.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationPermissionRequest.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationPermissionRequestManager.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationPosition.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" + +using namespace WebKit; + +GeolocationDispatcher::GeolocationDispatcher(RenderView* render_view) + : render_view_(render_view), + pending_permissions_(new WebGeolocationPermissionRequestManager()), + enable_high_accuracy_(false), + updating_(false) { +} + +GeolocationDispatcher::~GeolocationDispatcher() {} + +bool GeolocationDispatcher::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcher, message) + IPC_MESSAGE_HANDLER(ViewMsg_Geolocation_PermissionSet, + OnGeolocationPermissionSet) + IPC_MESSAGE_HANDLER(ViewMsg_Geolocation_PositionUpdated, + OnGeolocationPositionUpdated) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void GeolocationDispatcher::geolocationDestroyed() { + controller_.reset(); + DCHECK(!updating_); +} + +void GeolocationDispatcher::startUpdating() { + // TODO(jknotten): Remove url and bridge_id from StartUpdating message + // once we have switched over to client-based geolocation. + GURL url; + render_view_->Send(new ViewHostMsg_Geolocation_StartUpdating( + render_view_->routing_id(), -1, url, enable_high_accuracy_)); + updating_ = true; +} + +void GeolocationDispatcher::stopUpdating() { + // TODO(jknotten): Remove url and bridge_id from StopUpdating message + // once we have switched over to client-based geolocation. + render_view_->Send(new ViewHostMsg_Geolocation_StopUpdating( + render_view_->routing_id(), -1)); + updating_ = false; +} + +void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) { + // GeolocationController calls setEnableHighAccuracy(true) before + // startUpdating in response to the first high-accuracy Geolocation + // subscription. When the last high-accuracy Geolocation unsubscribes + // it calls setEnableHighAccuracy(false) after stopUpdating. + bool has_changed = enable_high_accuracy_ != enable_high_accuracy; + enable_high_accuracy_ = enable_high_accuracy; + // We have a different accuracy requirement. Request browser to update. + if (updating_ && has_changed) + startUpdating(); +} + +void GeolocationDispatcher::setController( + WebGeolocationController* controller) { + controller_.reset(controller); +} + +bool GeolocationDispatcher::lastPosition(WebGeolocationPosition&) { + // The latest position is stored in the browser, not the renderer, so we + // would have to fetch it synchronously to give a good value here. The + // WebCore::GeolocationController already caches the last position it + // receives, so there is not much benefit to more position caching here. + return false; +} + +// TODO(jknotten): Change the messages to use a security origin, so no +// conversion is necessary. +void GeolocationDispatcher::requestPermission( + const WebGeolocationPermissionRequest& permissionRequest) { + int bridge_id = pending_permissions_->add(permissionRequest); + string16 origin = permissionRequest.securityOrigin().toString(); + render_view_->Send(new ViewHostMsg_Geolocation_RequestPermission( + render_view_->routing_id(), bridge_id, GURL(origin))); +} + +// TODO(jknotten): Change the messages to use a security origin, so no +// conversion is necessary. +void GeolocationDispatcher::cancelPermissionRequest( + const WebGeolocationPermissionRequest& permissionRequest) { + int bridge_id; + if (!pending_permissions_->remove(permissionRequest, bridge_id)) + return; + string16 origin = permissionRequest.securityOrigin().toString(); + render_view_->Send(new ViewHostMsg_Geolocation_CancelPermissionRequest( + render_view_->routing_id(), bridge_id, GURL(origin))); +} + +// Permission for using geolocation has been set. +void GeolocationDispatcher::OnGeolocationPermissionSet( + int bridge_id, bool is_allowed) { + WebGeolocationPermissionRequest permissionRequest; + if (!pending_permissions_->remove(bridge_id, permissionRequest)) + return; + permissionRequest.setIsAllowed(is_allowed); +} + +// We have an updated geolocation position or error code. +void GeolocationDispatcher::OnGeolocationPositionUpdated( + const Geoposition& geoposition) { + DCHECK(updating_); + DCHECK(geoposition.IsInitialized()); + if (geoposition.IsValidFix()) { + controller_->positionChanged( + WebGeolocationPosition( + static_cast<int64>(geoposition.timestamp.ToDoubleT() * 1000), + geoposition.latitude, geoposition.longitude, + geoposition.accuracy, + geoposition.is_valid_altitude(), geoposition.altitude, + geoposition.is_valid_altitude_accuracy(), + geoposition.altitude_accuracy, + geoposition.is_valid_heading(), geoposition.heading, + geoposition.is_valid_speed(), geoposition.speed)); + } else { + WebGeolocationError::Error code; + switch (geoposition.error_code) { + case Geoposition::ERROR_CODE_PERMISSION_DENIED: + code = WebGeolocationError::ErrorPermissionDenied; + break; + case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE: + code = WebGeolocationError::ErrorPositionUnavailable; + break; + default: + DCHECK(false); + NOTREACHED() << geoposition.error_code; + return; + } + controller_->errorOccurred( + WebGeolocationError( + code, WebKit::WebString::fromUTF8(geoposition.error_message))); + } +} + +#endif // CLIENT_BASED_GEOLOCATION diff --git a/chrome/renderer/geolocation_dispatcher.h b/chrome/renderer/geolocation_dispatcher.h new file mode 100644 index 0000000..91c92a8 --- /dev/null +++ b/chrome/renderer/geolocation_dispatcher.h @@ -0,0 +1,75 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_RENDERER_GEOLOCATION_DISPATCHER_H_ +#define CHROME_RENDERER_GEOLOCATION_DISPATCHER_H_ +#pragma once + +#if defined(ENABLE_CLIENT_BASED_GEOLOCATION) + +#include "base/scoped_ptr.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebGeolocationController.h" + +class RenderView; +struct Geoposition; + +namespace WebKit { +class WebGeolocationController; +class WebGeolocationPermissionRequest; +class WebGeolocationPermissionRequestManager; +class WebGeolocationPosition; +class WebSecurityOrigin; +} + +namespace IPC { +class Message; +} + +// GeolocationDispatcher is a delegate for Geolocation messages used by +// WebKit. +// It's the complement of GeolocationDispatcherHost (owned by RenderViewHost). +class GeolocationDispatcher : public WebKit::WebGeolocationClient { + public: + explicit GeolocationDispatcher(RenderView* render_view); + virtual ~GeolocationDispatcher(); + + // IPC + bool OnMessageReceived(const IPC::Message& message); + + // WebGeolocationClient + virtual void geolocationDestroyed(); + virtual void startUpdating(); + virtual void stopUpdating(); + virtual void setEnableHighAccuracy(bool enable_high_accuracy); + virtual void setController(WebKit::WebGeolocationController* controller); + virtual bool lastPosition(WebKit::WebGeolocationPosition& position); + virtual void requestPermission( + const WebKit::WebGeolocationPermissionRequest& permissionRequest); + virtual void cancelPermissionRequest( + const WebKit::WebGeolocationPermissionRequest& permissionRequest); + + private: + // Permission for using geolocation has been set. + void OnGeolocationPermissionSet(int bridge_id, bool is_allowed); + + // We have an updated geolocation position or error code. + void OnGeolocationPositionUpdated(const Geoposition& geoposition); + + // GeolocationDispatcher is owned by RenderView. Back pointer for IPC. + RenderView* render_view_; + + // The controller_ is valid for the lifetime of the underlying + // WebCore::GeolocationController. geolocationDestroyed() is + // invoked when the underlying object is destroyed. + scoped_ptr< WebKit::WebGeolocationController> controller_; + + scoped_ptr<WebKit::WebGeolocationPermissionRequestManager> + pending_permissions_; + bool enable_high_accuracy_; + bool updating_; +}; +#endif // ENABLE_CLIENT_BASED_GEOLOCATION + +#endif // CHROME_RENDERER_GEOLOCATION_DISPATCHER_H_ diff --git a/chrome/renderer/geolocation_dispatcher_old.cc b/chrome/renderer/geolocation_dispatcher_old.cc index a6eff8b..4a235c7 100644 --- a/chrome/renderer/geolocation_dispatcher_old.cc +++ b/chrome/renderer/geolocation_dispatcher_old.cc @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if !defined(ENABLE_CLIENT_BASED_GEOLOCATION) #include "chrome/renderer/geolocation_dispatcher_old.h" - #include "base/command_line.h" #include "chrome/common/chrome_switches.h" #include "chrome/renderer/render_view.h" @@ -113,3 +113,4 @@ void GeolocationDispatcherOld::OnGeolocationPositionUpdated( } } } +#endif // !ENABLE_CLIENT_BASED_GEOLOCATION diff --git a/chrome/renderer/geolocation_dispatcher_old.h b/chrome/renderer/geolocation_dispatcher_old.h index 57f7d8a..51567ef 100644 --- a/chrome/renderer/geolocation_dispatcher_old.h +++ b/chrome/renderer/geolocation_dispatcher_old.h @@ -6,6 +6,10 @@ #define CHROME_RENDERER_GEOLOCATION_DISPATCHER_OLD_H_ #pragma once +#if !defined(ENABLE_CLIENT_BASED_GEOLOCATION) +// TODO(jknotten): Remove this class once the new client-based implementation is +// checked in (see http://crbug.com/59908). + #include "base/basictypes.h" #include "base/id_map.h" #include "ipc/ipc_message.h" @@ -21,8 +25,6 @@ struct Geoposition; // It's the complement of GeolocationDispatcherHostOld (owned by // RenderViewHost). -// TODO(jknotten): Remove this class once the new client-based implementation is -// checked in (see http://crbug.com/59908). class GeolocationDispatcherOld : public WebKit::WebGeolocationService { public: explicit GeolocationDispatcherOld(RenderView* render_view); @@ -61,4 +63,6 @@ class GeolocationDispatcherOld : public WebKit::WebGeolocationService { DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherOld); }; +#endif // ENABLE_CLIENT_BASED_GEOLOCATION + #endif // CHROME_RENDERER_GEOLOCATION_DISPATCHER_OLD_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index b639dd0..ca0c0e5 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -63,7 +63,11 @@ #include "chrome/renderer/extensions/renderer_extension_bindings.h" #include "chrome/renderer/external_host_bindings.h" #include "chrome/renderer/external_popup_menu.h" +#if ENABLE_CLIENT_BASED_GEOLOCATION +#include "chrome/renderer/geolocation_dispatcher.h" +#else #include "chrome/renderer/geolocation_dispatcher_old.h" +#endif #include "chrome/renderer/ggl/ggl.h" #include "chrome/renderer/localized_error.h" #include "chrome/renderer/media/audio_renderer_impl.h" @@ -5619,11 +5623,20 @@ void RenderView::OnPageTranslated() { autofill_helper_->FrameContentsAvailable(frame); } +#if defined(ENABLE_CLIENT_BASED_GEOLOCATION) +WebKit::WebGeolocationClient* RenderView::geolocationClient() +{ + if (!geolocation_dispatcher_.get()) + geolocation_dispatcher_.reset(new GeolocationDispatcher(this)); + return geolocation_dispatcher_.get(); +} +#else WebKit::WebGeolocationService* RenderView::geolocationService() { if (!geolocation_dispatcher_.get()) geolocation_dispatcher_.reset(new GeolocationDispatcherOld(this)); return geolocation_dispatcher_.get(); } +#endif WebKit::WebSpeechInputController* RenderView::speechInputController( WebKit::WebSpeechInputListener* listener) { diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index cdd2102..8b0fb5b 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -64,6 +64,7 @@ class DomAutomationController; class DOMUIBindings; class ExternalHostBindings; class FilePath; +class GeolocationDispatcher; class GeolocationDispatcherOld; class GURL; class ListValue; @@ -120,6 +121,7 @@ class WebDataSource; class WebDocument; class WebDragData; class WebFrame; +class WebGeolocationClient; class WebGeolocationServiceInterface; class WebImage; class WebInputElement; @@ -482,7 +484,11 @@ class RenderView : public RenderWidget, virtual void didClearAutoFillSelection(const WebKit::WebNode& node); virtual void didAcceptAutocompleteSuggestion( const WebKit::WebInputElement& element); +#if defined(ENABLE_CLIENT_BASED_GEOLOCATION) + virtual WebKit::WebGeolocationClient* geolocationClient(); +#else virtual WebKit::WebGeolocationService* geolocationService(); +#endif virtual WebKit::WebSpeechInputController* speechInputController( WebKit::WebSpeechInputListener* listener); virtual WebKit::WebDeviceOrientationClient* deviceOrientationClient(); @@ -1374,7 +1380,11 @@ class RenderView : public RenderWidget, scoped_refptr<AudioMessageFilter> audio_message_filter_; // The geolocation dispatcher attached to this view, lazily initialized. +#if ENABLE_CLIENT_BASED_GEOLOCATION + scoped_ptr<GeolocationDispatcher> geolocation_dispatcher_; +#else scoped_ptr<GeolocationDispatcherOld> geolocation_dispatcher_; +#endif // Handles accessibility requests into the renderer side, as well as // maintains the cache and other features of the accessibility tree. |