geolocation_dispatcher.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/geolocation_dispatcher.h" 6 7#include "content/common/geolocation_messages.h" 8#include "content/renderer/render_view_impl.h" 9#include "third_party/WebKit/public/platform/WebString.h" 10#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPermissionRequest.h" 11#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPermissionRequestManager.h" 12#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationClient.h" 13#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationPosition.h" 14#include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationError.h" 15 16using WebKit::WebGeolocationController; 17using WebKit::WebGeolocationError; 18using WebKit::WebGeolocationPermissionRequest; 19using WebKit::WebGeolocationPermissionRequestManager; 20using WebKit::WebGeolocationPosition; 21 22namespace content { 23 24GeolocationDispatcher::GeolocationDispatcher(RenderViewImpl* render_view) 25 : RenderViewObserver(render_view), 26 pending_permissions_(new WebGeolocationPermissionRequestManager()), 27 enable_high_accuracy_(false), 28 updating_(false) { 29} 30 31GeolocationDispatcher::~GeolocationDispatcher() {} 32 33bool GeolocationDispatcher::OnMessageReceived(const IPC::Message& message) { 34 bool handled = true; 35 IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcher, message) 36 IPC_MESSAGE_HANDLER(GeolocationMsg_PermissionSet, OnPermissionSet) 37 IPC_MESSAGE_HANDLER(GeolocationMsg_PositionUpdated, OnPositionUpdated) 38 IPC_MESSAGE_UNHANDLED(handled = false) 39 IPC_END_MESSAGE_MAP() 40 return handled; 41} 42 43void GeolocationDispatcher::geolocationDestroyed() { 44 controller_.reset(); 45 DCHECK(!updating_); 46} 47 48void GeolocationDispatcher::startUpdating() { 49 GURL url; 50 Send(new GeolocationHostMsg_StartUpdating( 51 routing_id(), url, enable_high_accuracy_)); 52 updating_ = true; 53} 54 55void GeolocationDispatcher::stopUpdating() { 56 Send(new GeolocationHostMsg_StopUpdating(routing_id())); 57 updating_ = false; 58} 59 60void GeolocationDispatcher::setEnableHighAccuracy(bool enable_high_accuracy) { 61 // GeolocationController calls setEnableHighAccuracy(true) before 62 // startUpdating in response to the first high-accuracy Geolocation 63 // subscription. When the last high-accuracy Geolocation unsubscribes 64 // it calls setEnableHighAccuracy(false) after stopUpdating. 65 bool has_changed = enable_high_accuracy_ != enable_high_accuracy; 66 enable_high_accuracy_ = enable_high_accuracy; 67 // We have a different accuracy requirement. Request browser to update. 68 if (updating_ && has_changed) 69 startUpdating(); 70} 71 72void GeolocationDispatcher::setController( 73 WebGeolocationController* controller) { 74 controller_.reset(controller); 75} 76 77bool GeolocationDispatcher::lastPosition(WebGeolocationPosition&) { 78 // The latest position is stored in the browser, not the renderer, so we 79 // would have to fetch it synchronously to give a good value here. The 80 // WebCore::GeolocationController already caches the last position it 81 // receives, so there is not much benefit to more position caching here. 82 return false; 83} 84 85// TODO(jknotten): Change the messages to use a security origin, so no 86// conversion is necessary. 87void GeolocationDispatcher::requestPermission( 88 const WebGeolocationPermissionRequest& permissionRequest) { 89 int bridge_id = pending_permissions_->add(permissionRequest); 90 string16 origin = permissionRequest.securityOrigin().toString(); 91 Send(new GeolocationHostMsg_RequestPermission( 92 routing_id(), bridge_id, GURL(origin))); 93} 94 95// TODO(jknotten): Change the messages to use a security origin, so no 96// conversion is necessary. 97void GeolocationDispatcher::cancelPermissionRequest( 98 const WebGeolocationPermissionRequest& permissionRequest) { 99 int bridge_id; 100 if (!pending_permissions_->remove(permissionRequest, bridge_id)) 101 return; 102 string16 origin = permissionRequest.securityOrigin().toString(); 103 Send(new GeolocationHostMsg_CancelPermissionRequest( 104 routing_id(), bridge_id, GURL(origin))); 105} 106 107// Permission for using geolocation has been set. 108void GeolocationDispatcher::OnPermissionSet(int bridge_id, bool is_allowed) { 109 WebGeolocationPermissionRequest permissionRequest; 110 if (!pending_permissions_->remove(bridge_id, permissionRequest)) 111 return; 112 permissionRequest.setIsAllowed(is_allowed); 113} 114 115// We have an updated geolocation position or error code. 116void GeolocationDispatcher::OnPositionUpdated( 117 const Geoposition& geoposition) { 118 // It is possible for the browser process to have queued an update message 119 // before receiving the stop updating message. 120 if (!updating_) 121 return; 122 123 if (geoposition.Validate()) { 124 controller_->positionChanged( 125 WebGeolocationPosition( 126 geoposition.timestamp.ToDoubleT(), 127 geoposition.latitude, geoposition.longitude, 128 geoposition.accuracy, 129 // Lowest point on land is at approximately -400 meters. 130 geoposition.altitude > -10000., 131 geoposition.altitude, 132 geoposition.altitude_accuracy >= 0., 133 geoposition.altitude_accuracy, 134 geoposition.heading >= 0. && geoposition.heading <= 360., 135 geoposition.heading, 136 geoposition.speed >= 0., 137 geoposition.speed)); 138 } else { 139 WebGeolocationError::Error code; 140 switch (geoposition.error_code) { 141 case Geoposition::ERROR_CODE_PERMISSION_DENIED: 142 code = WebGeolocationError::ErrorPermissionDenied; 143 break; 144 case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE: 145 code = WebGeolocationError::ErrorPositionUnavailable; 146 break; 147 default: 148 NOTREACHED() << geoposition.error_code; 149 return; 150 } 151 controller_->errorOccurred( 152 WebGeolocationError( 153 code, WebKit::WebString::fromUTF8(geoposition.error_message))); 154 } 155} 156 157} // namespace content 158