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

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: minus most test changes 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;
73 break;
74 case mojom::blink::Geoposition::ErrorCode::NONE:
75 case mojom::blink::Geoposition::ErrorCode::TIMEOUT:
76 ASSERT_NOT_REACHED();
Marijn Kruisselbrink 2016/05/06 20:12:15 ASSERT_NOT_REACHED() is deprecated in favor of NOT
Sam McNally 2016/05/10 10:06:08 Done.
76 break; 77 break;
77 } 78 }
79 return PositionError::create(errorCode, error);
80 }
78 81
79 return PositionError::create(code, error->message()); 82 } // namespace
80 }
81 83
82 Geolocation* Geolocation::create(ExecutionContext* context) 84 Geolocation* Geolocation::create(ExecutionContext* context)
83 { 85 {
84 Geolocation* geolocation = new Geolocation(context); 86 Geolocation* geolocation = new Geolocation(context);
85 geolocation->suspendIfNeeded(); 87 geolocation->suspendIfNeeded();
86 return geolocation; 88 return geolocation;
87 } 89 }
88 90
89 Geolocation::Geolocation(ExecutionContext* context) 91 Geolocation::Geolocation(ExecutionContext* context)
90 : ActiveDOMObject(context) 92 : ActiveDOMObject(context)
93 , PageLifecycleObserver(document()->page())
91 , m_geolocationPermission(PermissionUnknown) 94 , m_geolocationPermission(PermissionUnknown)
92 { 95 {
96 ThreadState::current()->registerPreFinalizer(this);
93 } 97 }
94 98
95 Geolocation::~Geolocation() 99 Geolocation::~Geolocation()
96 { 100 {
97 ASSERT(m_geolocationPermission != PermissionRequested); 101 ASSERT(m_geolocationPermission != PermissionRequested);
98 } 102 }
99 103
100 DEFINE_TRACE(Geolocation) 104 DEFINE_TRACE(Geolocation)
101 { 105 {
102 visitor->trace(m_oneShots); 106 visitor->trace(m_oneShots);
103 visitor->trace(m_watchers); 107 visitor->trace(m_watchers);
104 visitor->trace(m_pendingForPermissionNotifiers); 108 visitor->trace(m_pendingForPermissionNotifiers);
105 visitor->trace(m_lastPosition); 109 visitor->trace(m_lastPosition);
106 visitor->trace(m_requestsAwaitingCachedPosition);
107 ActiveDOMObject::trace(visitor); 110 ActiveDOMObject::trace(visitor);
111 PageLifecycleObserver::trace(visitor);
108 } 112 }
109 113
110 Document* Geolocation::document() const 114 Document* Geolocation::document() const
111 { 115 {
112 return toDocument(getExecutionContext()); 116 return toDocument(getExecutionContext());
113 } 117 }
114 118
115 LocalFrame* Geolocation::frame() const 119 LocalFrame* Geolocation::frame() const
116 { 120 {
117 return document() ? document()->frame() : 0; 121 return document() ? document()->frame() : 0;
118 } 122 }
119 123
120 void Geolocation::stop() 124 void Geolocation::stop()
Michael van Ouwerkerk 2016/05/09 17:22:31 I think this should also stop observing Page: "Pag
Sam McNally 2016/05/10 10:06:08 Done.
dcheng 2016/05/10 23:55:29 I don't think a swept Page should be doing any vis
Michael van Ouwerkerk 2016/05/11 12:38:30 The issue seems to be that while ContextLifecycleO
121 { 125 {
122 LocalFrame* frame = this->frame(); 126 if (m_permissionService)
123 if (frame && m_geolocationPermission == PermissionRequested) 127 m_permissionService.reset();
124 GeolocationController::from(frame)->cancelPermissionRequest(this);
125 128
126 // The frame may be moving to a new page and we want to get the permissions from the new page's client. 129 // The frame may be moving to a new page and we want to get the permissions from the new page's permission service.
Michael van Ouwerkerk 2016/05/09 17:22:31 I think there's more that has changed than just Ge
dcheng 2016/05/09 18:22:29 I don't understand this comment. What does it mean
Sam McNally 2016/05/10 10:06:08 I didn't think that Geolocation objects would be r
127 m_geolocationPermission = PermissionUnknown; 130 m_geolocationPermission = PermissionUnknown;
128 cancelAllRequests(); 131 cancelAllRequests();
129 stopUpdating(); 132 stopUpdating();
130 m_pendingForPermissionNotifiers.clear(); 133 m_pendingForPermissionNotifiers.clear();
131 } 134 m_lastPosition = nullptr;
132
133 Geoposition* Geolocation::lastPosition()
134 {
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;
142 } 135 }
143 136
144 void Geolocation::recordOriginTypeAccess() const 137 void Geolocation::recordOriginTypeAccess() const
145 { 138 {
146 ASSERT(frame()); 139 ASSERT(frame());
147 140
148 Document* document = this->document(); 141 Document* document = this->document();
149 ASSERT(document); 142 ASSERT(document);
150 143
151 // It is required by isSecureContext() but isn't 144 // It is required by isSecureContext() but isn't
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 if (isDenied()) 196 if (isDenied())
204 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage)); 197 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage));
205 else if (haveSuitableCachedPosition(notifier->options())) 198 else if (haveSuitableCachedPosition(notifier->options()))
206 notifier->setUseCachedPosition(); 199 notifier->setUseCachedPosition();
207 else if (!notifier->options().timeout()) 200 else if (!notifier->options().timeout())
208 notifier->startTimer(); 201 notifier->startTimer();
209 else if (!isAllowed()) { 202 else if (!isAllowed()) {
210 // if we don't yet have permission, request for permission before callin g startUpdating() 203 // if we don't yet have permission, request for permission before callin g startUpdating()
211 m_pendingForPermissionNotifiers.add(notifier); 204 m_pendingForPermissionNotifiers.add(notifier);
212 requestPermission(); 205 requestPermission();
213 } else if (startUpdating(notifier)) 206 } else {
207 startUpdating(notifier);
214 notifier->startTimer(); 208 notifier->startTimer();
215 else 209 }
216 notifier->setFatalError(PositionError::create(PositionError::POSITION_UN AVAILABLE, failedToStartServiceErrorMessage));
217 } 210 }
218 211
219 void Geolocation::fatalErrorOccurred(GeoNotifier* notifier) 212 void Geolocation::fatalErrorOccurred(GeoNotifier* notifier)
220 { 213 {
221 // This request has failed fatally. Remove it from our lists. 214 // This request has failed fatally. Remove it from our lists.
222 m_oneShots.remove(notifier); 215 m_oneShots.remove(notifier);
223 m_watchers.remove(notifier); 216 m_watchers.remove(notifier);
224 217
225 if (!hasListeners()) 218 if (!hasListeners())
226 stopUpdating(); 219 stopUpdating();
227 } 220 }
228 221
229 void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier) 222 void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier)
230 { 223 {
231 // This is called asynchronously, so the permissions could have been denied 224 DCHECK(isAllowed());
232 // since we last checked in startRequest. 225
233 if (isDenied()) { 226 notifier->runSuccessCallback(m_lastPosition);
234 notifier->setFatalError(PositionError::create(PositionError::PERMISSION_ DENIED, permissionDeniedErrorMessage)); 227
235 return; 228 // If this is a one-shot request, stop it. Otherwise, if the watch still
229 // exists, start the service to get updates.
230 if (m_oneShots.contains(notifier)) {
231 m_oneShots.remove(notifier);
232 } else if (m_watchers.contains(notifier)) {
233 if (notifier->options().timeout())
234 startUpdating(notifier);
235 notifier->startTimer();
236 } 236 }
237 237
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()) 238 if (!hasListeners())
273 stopUpdating(); 239 stopUpdating();
274 } 240 }
275 241
276 void Geolocation::requestTimedOut(GeoNotifier* notifier) 242 void Geolocation::requestTimedOut(GeoNotifier* notifier)
277 { 243 {
278 // If this is a one-shot request, stop it. 244 // If this is a one-shot request, stop it.
279 m_oneShots.remove(notifier); 245 m_oneShots.remove(notifier);
280 246
281 if (!hasListeners()) 247 if (!hasListeners())
282 stopUpdating(); 248 stopUpdating();
283 } 249 }
284 250
285 bool Geolocation::haveSuitableCachedPosition(const PositionOptions& options) 251 bool Geolocation::haveSuitableCachedPosition(const PositionOptions& options)
286 { 252 {
287 Geoposition* cachedPosition = lastPosition(); 253 if (!m_lastPosition)
288 if (!cachedPosition)
289 return false; 254 return false;
255 DCHECK(isAllowed());
290 if (!options.maximumAge()) 256 if (!options.maximumAge())
291 return false; 257 return false;
292 DOMTimeStamp currentTimeMillis = convertSecondsToDOMTimeStamp(currentTime()) ; 258 DOMTimeStamp currentTimeMillis = convertSecondsToDOMTimeStamp(currentTime()) ;
293 return cachedPosition->timestamp() > currentTimeMillis - options.maximumAge( ); 259 return m_lastPosition->timestamp() > currentTimeMillis - options.maximumAge( );
294 } 260 }
295 261
296 void Geolocation::clearWatch(int watchID) 262 void Geolocation::clearWatch(int watchID)
297 { 263 {
298 if (watchID <= 0) 264 if (watchID <= 0)
299 return; 265 return;
300 266
301 if (GeoNotifier* notifier = m_watchers.find(watchID)) 267 if (GeoNotifier* notifier = m_watchers.find(watchID))
302 m_pendingForPermissionNotifiers.remove(notifier); 268 m_pendingForPermissionNotifiers.remove(notifier);
303 m_watchers.remove(watchID); 269 m_watchers.remove(watchID);
304 270
305 if (!hasListeners()) 271 if (!hasListeners())
306 stopUpdating(); 272 stopUpdating();
307 } 273 }
308 274
309 void Geolocation::setIsAllowed(bool allowed) 275 void Geolocation::onGeolocationPermissionUpdated(mojom::blink::PermissionStatus status)
310 { 276 {
311 // This may be due to either a new position from the service, or a cached po sition. 277 // This may be due to either a new position from the service, or a cached po sition.
312 m_geolocationPermission = allowed ? PermissionAllowed : PermissionDenied; 278 m_geolocationPermission = status == mojom::blink::PermissionStatus::GRANTED ? PermissionAllowed : PermissionDenied;
279 m_permissionService.reset();
313 280
314 // Permission request was made during the startRequest process 281 // While we iterate through the list, we need not worry about the list being modified as the permission
315 if (!m_pendingForPermissionNotifiers.isEmpty()) { 282 // is already set to Yes/No and no new listeners will be added to the pendin g list.
316 handlePendingPermissionNotifiers(); 283 for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) {
317 m_pendingForPermissionNotifiers.clear(); 284 if (isAllowed()) {
318 return; 285 // Start all pending notification requests as permission granted.
286 // The notifier is always ref'ed by m_oneShots or m_watchers.
287 startUpdating(notifier);
288 notifier->startTimer();
289 } else {
290 notifier->setFatalError(PositionError::create(PositionError::PERMISS ION_DENIED, permissionDeniedErrorMessage));
291 }
319 } 292 }
320 293 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 } 294 }
337 295
338 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) 296 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error)
339 { 297 {
340 for (GeoNotifier* notifier : notifiers) 298 for (GeoNotifier* notifier : notifiers)
341 notifier->runErrorCallback(error); 299 notifier->runErrorCallback(error);
342 } 300 }
343 301
344 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi on) 302 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi on)
345 { 303 {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 void Geolocation::requestPermission() 406 void Geolocation::requestPermission()
449 { 407 {
450 if (m_geolocationPermission != PermissionUnknown) 408 if (m_geolocationPermission != PermissionUnknown)
451 return; 409 return;
452 410
453 LocalFrame* frame = this->frame(); 411 LocalFrame* frame = this->frame();
454 if (!frame) 412 if (!frame)
455 return; 413 return;
456 414
457 m_geolocationPermission = PermissionRequested; 415 m_geolocationPermission = PermissionRequested;
416 frame->serviceRegistry()->connectToRemoteService(
417 mojo::GetProxy(&m_permissionService));
418 m_permissionService.set_connection_error_handler(sameThreadBindForMojo(&Geol ocation::onPermissionConnectionError, this));
458 419
459 // Ask the embedder: it maintains the geolocation challenge policy itself. 420 // Ask the embedder: it maintains the geolocation challenge policy itself.
460 GeolocationController::from(frame)->requestPermission(this); 421 m_permissionService->RequestPermission(
422 mojom::blink::PermissionName::GEOLOCATION,
423 getExecutionContext()->getSecurityOrigin()->toString(),
424 sameThreadBindForMojo(&Geolocation::onGeolocationPermissionUpdated, this ));
461 } 425 }
462 426
463 void Geolocation::makeSuccessCallbacks() 427 void Geolocation::makeSuccessCallbacks()
464 { 428 {
465 ASSERT(lastPosition()); 429 ASSERT(m_lastPosition);
466 ASSERT(isAllowed()); 430 ASSERT(isAllowed());
467 431
468 GeoNotifierVector oneShotsCopy; 432 GeoNotifierVector oneShotsCopy;
469 copyToVector(m_oneShots, oneShotsCopy); 433 copyToVector(m_oneShots, oneShotsCopy);
470 434
471 GeoNotifierVector watchersCopy; 435 GeoNotifierVector watchersCopy;
472 m_watchers.getNotifiersVector(watchersCopy); 436 m_watchers.getNotifiersVector(watchersCopy);
473 437
474 // Clear the lists before we make the callbacks, to avoid clearing notifiers 438 // 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 439 // added by calls to Geolocation methods from the callbacks, and to prevent
476 // further callbacks to these notifiers. 440 // further callbacks to these notifiers.
477 m_oneShots.clear(); 441 m_oneShots.clear();
478 442
479 // Also clear the set of notifiers waiting for a cached position. All the 443 sendPosition(oneShotsCopy, m_lastPosition);
480 // oneshots and watchers will receive a position now, and if they happen to 444 sendPosition(watchersCopy, m_lastPosition);
481 // be lingering in that set, avoid this bug: http://crbug.com/311876 .
482 m_requestsAwaitingCachedPosition.clear();
483
484 sendPosition(oneShotsCopy, lastPosition());
485 sendPosition(watchersCopy, lastPosition());
486 445
487 if (!hasListeners()) 446 if (!hasListeners())
488 stopUpdating(); 447 stopUpdating();
489 } 448 }
490 449
491 void Geolocation::positionChanged() 450 void Geolocation::positionChanged()
492 { 451 {
493 ASSERT(isAllowed()); 452 ASSERT(isAllowed());
494 453
495 // Stop all currently running timers. 454 // Stop all currently running timers.
496 stopTimers(); 455 stopTimers();
497 456
498 makeSuccessCallbacks(); 457 makeSuccessCallbacks();
499 } 458 }
500 459
501 void Geolocation::setError(GeolocationError* error) 460 void Geolocation::startUpdating(GeoNotifier* notifier)
502 { 461 {
503 handleError(createPositionError(error)); 462 // This may be called multiple times, though stopUpdating() is called only
Michael van Ouwerkerk 2016/05/09 17:22:31 There are many calls to stopUpdating(). What did y
Sam McNally 2016/05/10 10:06:08 It was copy-pasted from GeolocationController and
504 } 463 // once.
505 464 m_updating = true;
506 bool Geolocation::startUpdating(GeoNotifier* notifier) 465 if (notifier->options().enableHighAccuracy() && !m_enableHighAccuracy) {
507 { 466 m_enableHighAccuracy = true;
508 LocalFrame* frame = this->frame(); 467 if (m_geolocationService)
509 if (!frame) 468 m_geolocationService->SetHighAccuracy(true);
510 return false; 469 }
511 470 updateGeolocationServiceConnection();
512 GeolocationController::from(frame)->addObserver(this, notifier->options().en ableHighAccuracy());
513 return true;
514 } 471 }
515 472
516 void Geolocation::stopUpdating() 473 void Geolocation::stopUpdating()
517 { 474 {
518 LocalFrame* frame = this->frame(); 475 m_updating = false;
519 if (!frame) 476 updateGeolocationServiceConnection();
477 m_enableHighAccuracy = false;
478 }
479
480 void Geolocation::updateGeolocationServiceConnection()
481 {
482 if (!page() || !page()->isPageVisible() || !m_updating) {
Michael van Ouwerkerk 2016/05/09 17:22:31 This should also check that getExecutionContext()
Sam McNally 2016/05/10 10:06:08 Done.
483 m_geolocationService.reset();
484 m_disconnectedGeolocationService = true;
485 return;
486 }
487 if (m_geolocationService)
520 return; 488 return;
521 489
522 GeolocationController::from(frame)->removeObserver(this); 490 frame()->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_geoloca tionService));
491 m_geolocationService.set_connection_error_handler(sameThreadBindForMojo(&Geo location::onGeolocationConnectionError, this));
492 if (m_enableHighAccuracy)
493 m_geolocationService->SetHighAccuracy(true);
494 queryNextPosition();
523 } 495 }
524 496
525 void Geolocation::handlePendingPermissionNotifiers() 497 void Geolocation::queryNextPosition()
526 { 498 {
527 // While we iterate through the list, we need not worry about list being mod ified as the permission 499 m_geolocationService->QueryNextPosition(
528 // is already set to Yes/No and no new listeners will be added to the pendin g list. 500 sameThreadBindForMojo(&Geolocation::onPositionUpdated, this));
529 for (GeoNotifier* notifier : m_pendingForPermissionNotifiers) { 501 }
530 if (isAllowed()) { 502
531 // start all pending notification requests as permission granted. 503 void Geolocation::onPositionUpdated(mojom::blink::GeopositionPtr position)
532 // The notifier is always ref'ed by m_oneShots or m_watchers. 504 {
533 if (startUpdating(notifier)) 505 m_disconnectedGeolocationService = false;
534 notifier->startTimer(); 506 if (position->valid) {
535 else 507 m_lastPosition = createGeoposition(*position);
536 notifier->setFatalError(PositionError::create(PositionError::POS ITION_UNAVAILABLE, failedToStartServiceErrorMessage)); 508 positionChanged();
537 } else { 509 } else {
538 notifier->setFatalError(PositionError::create(PositionError::PERMISS ION_DENIED, permissionDeniedErrorMessage)); 510 handleError(createPositionError(position->error_code, position->error_me ssage));
539 }
540 } 511 }
512 if (!m_disconnectedGeolocationService)
513 queryNextPosition();
514 }
515
516 void Geolocation::pageVisibilityChanged()
517 {
518 updateGeolocationServiceConnection();
519 }
520
521 void Geolocation::onGeolocationConnectionError()
522 {
523 PositionError* error = PositionError::create(PositionError::POSITION_UNAVAIL ABLE, failedToStartServiceErrorMessage);
524 error->setIsFatal(true);
525 handleError(error);
526 }
527
528 void Geolocation::onPermissionConnectionError()
529 {
530 onGeolocationPermissionUpdated(mojom::blink::PermissionStatus::DENIED);
541 } 531 }
542 532
543 } // namespace blink 533 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698