Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: third_party/WebKit/Source/modules/geolocation/Geolocation.cpp

Issue 1367853002: Move GeolocationDispatcher into blink. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009 Torch Mobile, Inc. 3 * Copyright (C) 2009 Torch Mobile, Inc.
4 * Copyright 2010, The Android Open Source Project 4 * Copyright 2010, The Android Open Source Project
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 14 matching lines...) Expand all
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "modules/geolocation/Geolocation.h" 28 #include "modules/geolocation/Geolocation.h"
29 29
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/frame/Deprecation.h" 31 #include "core/frame/Deprecation.h"
32 #include "core/frame/OriginsUsingFeatures.h" 32 #include "core/frame/OriginsUsingFeatures.h"
33 #include "core/frame/Settings.h" 33 #include "core/frame/Settings.h"
34 #include "modules/geolocation/Coordinates.h" 34 #include "modules/geolocation/Coordinates.h"
35 #include "modules/geolocation/GeolocationController.h"
36 #include "modules/geolocation/GeolocationError.h" 35 #include "modules/geolocation/GeolocationError.h"
37 #include "modules/geolocation/GeolocationPosition.h" 36 #include "platform/mojo/MojoHelper.h"
38 #include "platform/weborigin/SecurityOrigin.h" 37 #include "public/platform/ServiceRegistry.h"
39 #include "wtf/CurrentTime.h" 38 #include "wtf/CurrentTime.h"
40 39
41 namespace blink { 40 namespace blink {
41 namespace {
42 42
43 static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; 43 static const char permissionDeniedErrorMessage[] = "User denied Geolocation";
44 static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocat ion service"; 44 static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocat ion service";
45 static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used in frameless documents"; 45 static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used in frameless documents";
46 46
47 static Geoposition* createGeoposition(GeolocationPosition* position) 47 static Geoposition* createGeoposition(const mojom::blink::Geoposition& position)
48 { 48 {
49 if (!position)
50 return nullptr;
51
52 Coordinates* coordinates = Coordinates::create( 49 Coordinates* coordinates = Coordinates::create(
53 position->latitude(), 50 position.latitude,
54 position->longitude(), 51 position.longitude,
55 position->canProvideAltitude(), 52 position.altitude > -10000.,
56 position->altitude(), 53 position.altitude,
57 position->accuracy(), 54 position.accuracy,
58 position->canProvideAltitudeAccuracy(), 55 position.altitude_accuracy >= 0.,
59 position->altitudeAccuracy(), 56 position.altitude_accuracy,
60 position->canProvideHeading(), 57 position.heading >= 0. && position.heading <= 360.,
61 position->heading(), 58 position.heading,
62 position->canProvideSpeed(), 59 position.speed >= 0.,
63 position->speed()); 60 position.speed);
64 return Geoposition::create(coordinates, convertSecondsToDOMTimeStamp(positio n->timestamp())); 61 return Geoposition::create(coordinates, convertSecondsToDOMTimeStamp(positio n.timestamp));
65 } 62 }
66 63
67 static PositionError* createPositionError(GeolocationError* error) 64 static PositionError* createPositionError(mojom::blink::Geoposition::ErrorCode m ojomErrorCode, const String& error)
68 { 65 {
69 PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; 66 PositionError::ErrorCode errorCode = PositionError::POSITION_UNAVAILABLE;
70 switch (error->code()) { 67 switch (mojomErrorCode) {
71 case GeolocationError::PermissionDenied: 68 case mojom::blink::Geoposition::ErrorCode::PERMISSION_DENIED:
72 code = PositionError::PERMISSION_DENIED; 69 errorCode = PositionError::PERMISSION_DENIED;
73 break; 70 break;
74 case GeolocationError::PositionUnavailable: 71 case mojom::blink::Geoposition::ErrorCode::POSITION_UNAVAILABLE:
75 code = PositionError::POSITION_UNAVAILABLE; 72 errorCode = PositionError::POSITION_UNAVAILABLE;
76 break; 73 break;
74 default:
Michael van Ouwerkerk 2016/05/04 13:52:16 Doesn't clang fail the build when a switch fails t
Sam McNally 2016/05/05 11:50:24 Done.
75 ASSERT_NOT_REACHED();
77 } 76 }
77 return PositionError::create(errorCode, error);
78 }
78 79
79 return PositionError::create(code, error->message()); 80 } // namespace
80 }
81 81
82 Geolocation* Geolocation::create(ExecutionContext* context) 82 Geolocation* Geolocation::create(ExecutionContext* context)
83 { 83 {
84 Geolocation* geolocation = new Geolocation(context); 84 Geolocation* geolocation = new Geolocation(context);
85 geolocation->suspendIfNeeded(); 85 geolocation->suspendIfNeeded();
86 return geolocation; 86 return geolocation;
87 } 87 }
88 88
89 Geolocation::Geolocation(ExecutionContext* context) 89 Geolocation::Geolocation(ExecutionContext* context)
90 : ActiveDOMObject(context) 90 : ActiveDOMObject(context)
91 , PageLifecycleObserver(document()->page())
91 , m_geolocationPermission(PermissionUnknown) 92 , m_geolocationPermission(PermissionUnknown)
92 { 93 {
93 } 94 }
94 95
95 Geolocation::~Geolocation() 96 Geolocation::~Geolocation()
96 { 97 {
97 ASSERT(m_geolocationPermission != PermissionRequested); 98 ASSERT(m_geolocationPermission != PermissionRequested);
98 } 99 }
99 100
100 DEFINE_TRACE(Geolocation) 101 DEFINE_TRACE(Geolocation)
101 { 102 {
102 visitor->trace(m_oneShots); 103 visitor->trace(m_oneShots);
103 visitor->trace(m_watchers); 104 visitor->trace(m_watchers);
104 visitor->trace(m_pendingForPermissionNotifiers); 105 visitor->trace(m_pendingForPermissionNotifiers);
105 visitor->trace(m_lastPosition); 106 visitor->trace(m_lastPosition);
106 visitor->trace(m_requestsAwaitingCachedPosition);
107 ActiveDOMObject::trace(visitor); 107 ActiveDOMObject::trace(visitor);
108 PageLifecycleObserver::trace(visitor);
108 } 109 }
109 110
110 Document* Geolocation::document() const 111 Document* Geolocation::document() const
111 { 112 {
112 return toDocument(getExecutionContext()); 113 return toDocument(getExecutionContext());
113 } 114 }
114 115
115 LocalFrame* Geolocation::frame() const 116 LocalFrame* Geolocation::frame() const
116 { 117 {
117 return document() ? document()->frame() : 0; 118 return document() ? document()->frame() : 0;
118 } 119 }
119 120
120 void Geolocation::stop() 121 void Geolocation::stop()
121 { 122 {
122 LocalFrame* frame = this->frame(); 123 if (m_permissionService)
Michael van Ouwerkerk 2016/05/04 13:52:16 Why not also stop m_geolocationService?
Sam McNally 2016/05/05 11:50:24 stopUpdating() stops it.
123 if (frame && m_geolocationPermission == PermissionRequested) 124 m_permissionService.reset();
124 GeolocationController::from(frame)->cancelPermissionRequest(this);
125 125
126 // The frame may be moving to a new page and we want to get the permissions from the new page's client. 126 // The frame may be moving to a new page and we want to get the permissions from the new page's client.
Michael van Ouwerkerk 2016/05/04 13:52:16 Please update this comment, there is no client any
Sam McNally 2016/05/05 11:50:24 Done.
127 m_geolocationPermission = PermissionUnknown; 127 m_geolocationPermission = PermissionUnknown;
128 cancelAllRequests(); 128 cancelAllRequests();
129 stopUpdating(); 129 stopUpdating();
130 m_pendingForPermissionNotifiers.clear(); 130 m_pendingForPermissionNotifiers.clear();
131 m_lastPosition = nullptr;
131 } 132 }
132 133
133 Geoposition* Geolocation::lastPosition() 134 Geoposition* Geolocation::lastPosition()
Michael van Ouwerkerk 2016/05/04 13:52:16 This can be in the header now, or removed entirely
Sam McNally 2016/05/05 11:50:24 Done.
134 { 135 {
135 LocalFrame* frame = this->frame();
136 if (!frame)
137 return 0;
138
139 m_lastPosition = createGeoposition(GeolocationController::from(frame)->lastP osition());
140
141 return m_lastPosition; 136 return m_lastPosition;
142 } 137 }
143 138
144 void Geolocation::recordOriginTypeAccess() const 139 void Geolocation::recordOriginTypeAccess() const
145 { 140 {
146 ASSERT(frame()); 141 ASSERT(frame());
147 142
148 Document* document = this->document(); 143 Document* document = this->document();
149 ASSERT(document); 144 ASSERT(document);
150 145
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 String errorMessage; 190 String errorMessage;
196 if (!frame()->settings()->allowGeolocationOnInsecureOrigins() && !getExecuti onContext()->isSecureContext(errorMessage)) { 191 if (!frame()->settings()->allowGeolocationOnInsecureOrigins() && !getExecuti onContext()->isSecureContext(errorMessage)) {
197 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, errorMessage)); 192 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, errorMessage));
198 return; 193 return;
199 } 194 }
200 195
201 // Check whether permissions have already been denied. Note that if this is the case, 196 // Check whether permissions have already been denied. Note that if this is the case,
202 // the permission state can not change again in the lifetime of this page. 197 // the permission state can not change again in the lifetime of this page.
203 if (isDenied()) 198 if (isDenied())
204 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage)); 199 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage));
205 else if (haveSuitableCachedPosition(notifier->options())) 200 else if (isAllowed() && haveSuitableCachedPosition(notifier->options()))
Michael van Ouwerkerk 2016/05/04 13:52:16 Why add the isAllowed call? Is it for readability?
Sam McNally 2016/05/05 11:50:24 It was for readability. Removed it and added a DCH
206 notifier->setUseCachedPosition(); 201 notifier->setUseCachedPosition();
207 else if (!notifier->options().timeout()) 202 else if (!notifier->options().timeout())
208 notifier->startTimer(); 203 notifier->startTimer();
209 else if (!isAllowed()) { 204 else if (!isAllowed()) {
210 // if we don't yet have permission, request for permission before callin g startUpdating() 205 // if we don't yet have permission, request for permission before callin g startUpdating()
211 m_pendingForPermissionNotifiers.add(notifier); 206 m_pendingForPermissionNotifiers.add(notifier);
212 requestPermission(); 207 requestPermission();
213 } else if (startUpdating(notifier)) 208 } else {
209 startUpdating(notifier);
214 notifier->startTimer(); 210 notifier->startTimer();
215 else 211 }
216 notifier->setFatalError(PositionError::create(PositionError::POSITION_UN AVAILABLE, failedToStartServiceErrorMessage));
217 } 212 }
218 213
219 void Geolocation::fatalErrorOccurred(GeoNotifier* notifier) 214 void Geolocation::fatalErrorOccurred(GeoNotifier* notifier)
220 { 215 {
221 // This request has failed fatally. Remove it from our lists. 216 // This request has failed fatally. Remove it from our lists.
222 m_oneShots.remove(notifier); 217 m_oneShots.remove(notifier);
223 m_watchers.remove(notifier); 218 m_watchers.remove(notifier);
224 219
225 if (!hasListeners()) 220 if (!hasListeners())
226 stopUpdating(); 221 stopUpdating();
227 } 222 }
228 223
229 void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) 224 void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier)
230 { 225 {
231 // This is called asynchronously, so the permissions could have been denied 226 DCHECK(isAllowed());
Michael van Ouwerkerk 2016/05/04 13:52:16 This DCHECK is not equivalent to the isDenied() br
Sam McNally 2016/05/05 11:50:23 This should never be reached unless permission has
232 // since we last checked in startRequest. 227
233 if (isDenied()) { 228 notifier->runSuccessCallback(lastPosition());
234 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage)); 229
235 return; 230 // If this is a one-shot request, stop it. Otherwise, if the watch still
231 // exists, start the service to get updates.
232 if (m_oneShots.contains(notifier)) {
233 m_oneShots.remove(notifier);
234 } else if (m_watchers.contains(notifier)) {
235 if (notifier->options().timeout())
236 startUpdating(notifier);
237 notifier->startTimer();
236 } 238 }
237 239
238 m_requestsAwaitingCachedPosition.add(notifier);
239
240 // If permissions are allowed, make the callback
241 if (isAllowed()) {
242 makeCachedPositionCallbacks();
243 return;
244 }
245
246 // Request permissions, which may be synchronous or asynchronous.
247 requestPermission();
248 }
249
250 void Geolocation::makeCachedPositionCallbacks()
251 {
252 // All modifications to m_requestsAwaitingCachedPosition are done
253 // asynchronously, so we don't need to worry about it being modified from
254 // the callbacks.
255 for (GeoNotifier* notifier : m_requestsAwaitingCachedPosition) {
256 notifier->runSuccessCallback(lastPosition());
257
258 // If this is a one-shot request, stop it. Otherwise, if the watch still
259 // exists, start the service to get updates.
260 if (m_oneShots.contains(notifier))
261 m_oneShots.remove(notifier);
262 else if (m_watchers.contains(notifier)) {
263 if (!notifier->options().timeout() || startUpdating(notifier))
264 notifier->startTimer();
265 else
266 notifier->setFatalError(PositionError::create(PositionError::POS ITION_UNAVAILABLE, failedToStartServiceErrorMessage));
267 }
268 }
269
270 m_requestsAwaitingCachedPosition.clear();
271
272 if (!hasListeners()) 240 if (!hasListeners())
273 stopUpdating(); 241 stopUpdating();
274 } 242 }
275 243
276 void Geolocation::requestTimedOut(GeoNotifier* notifier) 244 void Geolocation::requestTimedOut(GeoNotifier* notifier)
277 { 245 {
278 // If this is a one-shot request, stop it. 246 // If this is a one-shot request, stop it.
279 m_oneShots.remove(notifier); 247 m_oneShots.remove(notifier);
280 248
281 if (!hasListeners()) 249 if (!hasListeners())
(...skipping 17 matching lines...) Expand all
299 return; 267 return;
300 268
301 if (GeoNotifier* notifier = m_watchers.find(watchID)) 269 if (GeoNotifier* notifier = m_watchers.find(watchID))
302 m_pendingForPermissionNotifiers.remove(notifier); 270 m_pendingForPermissionNotifiers.remove(notifier);
303 m_watchers.remove(watchID); 271 m_watchers.remove(watchID);
304 272
305 if (!hasListeners()) 273 if (!hasListeners())
306 stopUpdating(); 274 stopUpdating();
307 } 275 }
308 276
309 void Geolocation::setIsAllowed(bool allowed) 277 void Geolocation::onGeolocationPermissionUpdated(mojom::blink::PermissionStatus status)
310 { 278 {
311 // This may be due to either a new position from the service, or a cached po sition. 279 // This may be due to either a new position from the service, or a cached po sition.
312 m_geolocationPermission = allowed ? PermissionAllowed : PermissionDenied; 280 m_geolocationPermission = status == mojom::blink::PermissionStatus::GRANTED ? PermissionAllowed : PermissionDenied;
281 m_permissionService.reset();
313 282
314 // Permission request was made during the startRequest process 283 // While we iterate through the list, we need not worry about list being mod ified as the permission
Michael van Ouwerkerk 2016/05/04 13:52:16 s/list/the list/
Sam McNally 2016/05/05 11:50:24 Done.
315 if (!m_pendingForPermissionNotifiers.isEmpty()) { 284 // is already set to Yes/No and no new listeners will be added to the pendin g list.
316 handlePendingPermissionNotifiers(); 285 for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) {
317 m_pendingForPermissionNotifiers.clear(); 286 if (isAllowed()) {
318 return; 287 // start all pending notification requests as permission granted.
Michael van Ouwerkerk 2016/05/04 13:52:16 nit: s/start/Start/
Sam McNally 2016/05/05 11:50:24 Done.
288 // The notifier is always ref'ed by m_oneShots or m_watchers.
289 startUpdating(notifier);
290 notifier->startTimer();
291 } else {
292 notifier->setFatalError(PositionError::create(PositionError::PERMISS ION_DENIED, permissionDeniedErrorMessage));
293 }
319 } 294 }
320 295 m_pendingForPermissionNotifiers.clear();
321 if (!isAllowed()) {
322 PositionError* error = PositionError::create(PositionError::PERMISSION_D ENIED, permissionDeniedErrorMessage);
323 error->setIsFatal(true);
324 handleError(error);
325 m_requestsAwaitingCachedPosition.clear();
326 return;
327 }
328
329 // If the service has a last position, use it to call back for all requests.
330 // If any of the requests are waiting for permission for a cached position,
331 // the position from the service will be at least as fresh.
332 if (lastPosition())
333 makeSuccessCallbacks();
334 else
335 makeCachedPositionCallbacks();
336 } 296 }
337 297
338 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) 298 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error)
339 { 299 {
340 for (GeoNotifier* notifier : notifiers) 300 for (GeoNotifier* notifier : notifiers)
341 notifier->runErrorCallback(error); 301 notifier->runErrorCallback(error);
342 } 302 }
343 303
344 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi on) 304 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi on)
345 { 305 {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 void Geolocation::requestPermission() 408 void Geolocation::requestPermission()
449 { 409 {
450 if (m_geolocationPermission != PermissionUnknown) 410 if (m_geolocationPermission != PermissionUnknown)
451 return; 411 return;
452 412
453 LocalFrame* frame = this->frame(); 413 LocalFrame* frame = this->frame();
454 if (!frame) 414 if (!frame)
455 return; 415 return;
456 416
457 m_geolocationPermission = PermissionRequested; 417 m_geolocationPermission = PermissionRequested;
418 frame->serviceRegistry()->connectToRemoteService(
419 mojo::GetProxy(&m_permissionService));
420 m_permissionService.set_connection_error_handler(sameThreadBindForMojo(&Geol ocation::onPermissionConnectionError, this));
Michael van Ouwerkerk 2016/05/04 13:52:16 Under what circumstances does this get called?
Sam McNally 2016/05/05 11:50:23 Normally, this would only happen if the browser do
458 421
459 // Ask the embedder: it maintains the geolocation challenge policy itself. 422 // Ask the embedder: it maintains the geolocation challenge policy itself.
460 GeolocationController::from(frame)->requestPermission(this); 423 m_permissionService->RequestPermission(
424 mojom::blink::PermissionName::GEOLOCATION,
425 getExecutionContext()->getSecurityOrigin()->toString(),
426 sameThreadBindForMojo(&Geolocation::onGeolocationPermissionUpdated, this ));
461 } 427 }
462 428
463 void Geolocation::makeSuccessCallbacks() 429 void Geolocation::makeSuccessCallbacks()
464 { 430 {
465 ASSERT(lastPosition()); 431 ASSERT(lastPosition());
466 ASSERT(isAllowed()); 432 ASSERT(isAllowed());
467 433
468 GeoNotifierVector oneShotsCopy; 434 GeoNotifierVector oneShotsCopy;
469 copyToVector(m_oneShots, oneShotsCopy); 435 copyToVector(m_oneShots, oneShotsCopy);
470 436
471 GeoNotifierVector watchersCopy; 437 GeoNotifierVector watchersCopy;
472 m_watchers.getNotifiersVector(watchersCopy); 438 m_watchers.getNotifiersVector(watchersCopy);
473 439
474 // Clear the lists before we make the callbacks, to avoid clearing notifiers 440 // Clear the lists before we make the callbacks, to avoid clearing notifiers
475 // added by calls to Geolocation methods from the callbacks, and to prevent 441 // added by calls to Geolocation methods from the callbacks, and to prevent
476 // further callbacks to these notifiers. 442 // further callbacks to these notifiers.
477 m_oneShots.clear(); 443 m_oneShots.clear();
478 444
479 // Also clear the set of notifiers waiting for a cached position. All the
480 // oneshots and watchers will receive a position now, and if they happen to
481 // be lingering in that set, avoid this bug: http://crbug.com/311876 .
482 m_requestsAwaitingCachedPosition.clear();
483
484 sendPosition(oneShotsCopy, lastPosition()); 445 sendPosition(oneShotsCopy, lastPosition());
485 sendPosition(watchersCopy, lastPosition()); 446 sendPosition(watchersCopy, lastPosition());
486 447
487 if (!hasListeners()) 448 if (!hasListeners())
488 stopUpdating(); 449 stopUpdating();
489 } 450 }
490 451
491 void Geolocation::positionChanged() 452 void Geolocation::positionChanged()
492 { 453 {
493 ASSERT(isAllowed()); 454 ASSERT(isAllowed());
494 455
495 // Stop all currently running timers. 456 // Stop all currently running timers.
496 stopTimers(); 457 stopTimers();
497 458
498 makeSuccessCallbacks(); 459 makeSuccessCallbacks();
499 } 460 }
500 461
501 void Geolocation::setError(GeolocationError* error) 462 void Geolocation::startUpdating(GeoNotifier* notifier)
502 { 463 {
503 handleError(createPositionError(error)); 464 // This may be called multiple times, though stopUpdating() is called only
504 } 465 // once.
505 466 m_updating = true;
506 bool Geolocation::startUpdating(GeoNotifier* notifier) 467 if (notifier->options().enableHighAccuracy() && !m_enableHighAccuracy) {
507 { 468 m_enableHighAccuracy = true;
508 LocalFrame* frame = this->frame(); 469 if (m_geolocationService)
509 if (!frame) 470 m_geolocationService->SetHighAccuracy(true);
510 return false; 471 }
511 472 updateGeolocationServiceConnection();
512 GeolocationController::from(frame)->addObserver(this, notifier->options().en ableHighAccuracy());
513 return true;
514 } 473 }
515 474
516 void Geolocation::stopUpdating() 475 void Geolocation::stopUpdating()
517 { 476 {
518 LocalFrame* frame = this->frame(); 477 m_updating = false;
519 if (!frame) 478 updateGeolocationServiceConnection();
479 m_enableHighAccuracy = false;
480 }
481
482 void Geolocation::updateGeolocationServiceConnection()
483 {
484 if (!page() || page()->visibilityState() != PageVisibilityStateVisible || !m _updating) {
Michael van Ouwerkerk 2016/05/04 13:52:16 nit: use page()->isPageVisible()
Sam McNally 2016/05/05 11:50:24 Done.
485 m_geolocationService.reset();
486 m_queryInProgress = false;
487 return;
488 }
489 if (m_geolocationService)
520 return; 490 return;
521 491
522 GeolocationController::from(frame)->removeObserver(this); 492 frame()->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_geoloca tionService));
493 m_geolocationService.set_connection_error_handler(sameThreadBindForMojo(&Geo location::onGeolocationConnectionError, this));
494 if (m_enableHighAccuracy)
495 m_geolocationService->SetHighAccuracy(true);
496 queryNextPosition();
523 } 497 }
524 498
525 void Geolocation::handlePendingPermissionNotifiers() 499 void Geolocation::queryNextPosition()
526 { 500 {
527 // While we iterate through the list, we need not worry about list being mod ified as the permission 501 if (m_queryInProgress)
528 // is already set to Yes/No and no new listeners will be added to the pendin g list. 502 return;
529 for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) { 503
530 if (isAllowed()) { 504 m_queryInProgress = true;
531 // start all pending notification requests as permission granted. 505 m_geolocationService->QueryNextPosition(
532 // The notifier is always ref'ed by m_oneShots or m_watchers. 506 sameThreadBindForMojo(&Geolocation::onPositionUpdated, this));
533 if (startUpdating(notifier)) 507 }
534 notifier->startTimer(); 508
535 else 509 void Geolocation::onPositionUpdated(mojom::blink::GeopositionPtr position)
536 notifier->setFatalError(PositionError::create(PositionError::POS ITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 510 {
537 } else { 511 m_queryInProgress = false;
538 notifier->setFatalError(PositionError::create(PositionError::PERMISS ION_DENIED, permissionDeniedErrorMessage)); 512 if (position->valid) {
539 } 513 m_lastPosition = createGeoposition(*position);
514 positionChanged();
515 } else {
516 handleError(createPositionError(position->error_code, position->error_me ssage));
540 } 517 }
518 if (m_geolocationService)
519 queryNextPosition();
520 }
521
522 void Geolocation::pageVisibilityChanged()
523 {
524 updateGeolocationServiceConnection();
525 }
526
527 void Geolocation::onGeolocationConnectionError()
528 {
529 PositionError* error = PositionError::create(PositionError::POSITION_UNAVAIL ABLE, failedToStartServiceErrorMessage);
530 error->setIsFatal(true);
531 handleError(error);
532 }
533
534 void Geolocation::onPermissionConnectionError()
535 {
536 onGeolocationPermissionUpdated(mojom::blink::PermissionStatus::DENIED);
541 } 537 }
542 538
543 } // namespace blink 539 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698