| OLD | NEW |
| 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. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
| 14 * | 14 * |
| 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 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 "config.h" | 28 #include "config.h" |
| 29 #include "modules/geolocation/Geolocation.h" | 29 #include "modules/geolocation/Geolocation.h" |
| 30 | 30 |
| 31 #include "core/dom/Document.h" | 31 #include "core/dom/Document.h" |
| 32 #include "core/page/Frame.h" | 32 #include "core/page/Frame.h" |
| 33 #include "core/page/Page.h" | 33 #include "core/page/Page.h" |
| 34 #include "modules/geolocation/Geoposition.h" | 34 #include "modules/geolocation/Geoposition.h" |
| 35 #include "wtf/CurrentTime.h" | 35 #include "wtf/CurrentTime.h" |
| 36 | 36 |
| 37 #include "modules/geolocation/Coordinates.h" | 37 #include "modules/geolocation/Coordinates.h" |
| 38 #include "modules/geolocation/GeolocationController.h" | 38 #include "modules/geolocation/GeolocationController.h" |
| 39 #include "modules/geolocation/GeolocationError.h" | 39 #include "modules/geolocation/GeolocationError.h" |
| 40 #include "modules/geolocation/GeolocationPosition.h" | 40 #include "modules/geolocation/GeolocationPosition.h" |
| 41 #include "modules/geolocation/PositionError.h" | 41 #include "modules/geolocation/PositionError.h" |
| 42 | 42 |
| 43 namespace WebCore { | 43 namespace WebCore { |
| 44 | 44 |
| 45 static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; | 45 static const char permissionDeniedErrorMessage[] = "User denied Geolocation"; |
| 46 static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocat
ion service"; | 46 static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocat
ion service"; |
| 47 static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used
in frameless documents"; | 47 static const char framelessDocumentErrorMessage[] = "Geolocation cannot be used
in frameless documents"; |
| 48 | 48 |
| 49 static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position) | 49 static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position) |
| 50 { | 50 { |
| 51 if (!position) | 51 if (!position) |
| 52 return 0; | 52 return 0; |
| 53 | 53 |
| 54 RefPtr<Coordinates> coordinates = Coordinates::create(position->latitude(),
position->longitude(), position->canProvideAltitude(), position->altitude(), | 54 RefPtr<Coordinates> coordinates = Coordinates::create(position->latitude(),
position->longitude(), position->canProvideAltitude(), position->altitude(), |
| 55 position->accuracy(),
position->canProvideAltitudeAccuracy(), position->altitudeAccuracy(), | 55 position->accuracy(),
position->canProvideAltitudeAccuracy(), position->altitudeAccuracy(), |
| 56 position->canProvideHe
ading(), position->heading(), position->canProvideSpeed(), position->speed()); | 56 position->canProvideHe
ading(), position->heading(), position->canProvideSpeed(), position->speed()); |
| 57 return Geoposition::create(coordinates.release(), convertSecondsToDOMTimeSta
mp(position->timestamp())); | 57 return Geoposition::create(coordinates.release(), convertSecondsToDOMTimeSta
mp(position->timestamp())); |
| 58 } | 58 } |
| 59 | 59 |
| 60 static PassRefPtr<PositionError> createPositionError(GeolocationError* error) | 60 static PassRefPtr<PositionError> createPositionError(GeolocationError* error) |
| 61 { | 61 { |
| 62 PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; | 62 PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE; |
| 63 switch (error->code()) { | 63 switch (error->code()) { |
| 64 case GeolocationError::PermissionDenied: | 64 case GeolocationError::PermissionDenied: |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 } | 417 } |
| 418 | 418 |
| 419 void Geolocation::clearWatch(int watchID) | 419 void Geolocation::clearWatch(int watchID) |
| 420 { | 420 { |
| 421 if (watchID <= 0) | 421 if (watchID <= 0) |
| 422 return; | 422 return; |
| 423 | 423 |
| 424 if (GeoNotifier* notifier = m_watchers.find(watchID)) | 424 if (GeoNotifier* notifier = m_watchers.find(watchID)) |
| 425 m_pendingForPermissionNotifiers.remove(notifier); | 425 m_pendingForPermissionNotifiers.remove(notifier); |
| 426 m_watchers.remove(watchID); | 426 m_watchers.remove(watchID); |
| 427 | 427 |
| 428 if (!hasListeners()) | 428 if (!hasListeners()) |
| 429 stopUpdating(); | 429 stopUpdating(); |
| 430 } | 430 } |
| 431 | 431 |
| 432 void Geolocation::setIsAllowed(bool allowed) | 432 void Geolocation::setIsAllowed(bool allowed) |
| 433 { | 433 { |
| 434 // Protect the Geolocation object from garbage collection during a callback. | 434 // Protect the Geolocation object from garbage collection during a callback. |
| 435 RefPtr<Geolocation> protect(this); | 435 RefPtr<Geolocation> protect(this); |
| 436 | 436 |
| 437 // This may be due to either a new position from the service, or a cached | 437 // This may be due to either a new position from the service, or a cached |
| 438 // position. | 438 // position. |
| 439 m_allowGeolocation = allowed ? Yes : No; | 439 m_allowGeolocation = allowed ? Yes : No; |
| 440 | 440 |
| 441 // Permission request was made during the startRequest process | 441 // Permission request was made during the startRequest process |
| 442 if (!m_pendingForPermissionNotifiers.isEmpty()) { | 442 if (!m_pendingForPermissionNotifiers.isEmpty()) { |
| 443 handlePendingPermissionNotifiers(); | 443 handlePendingPermissionNotifiers(); |
| 444 m_pendingForPermissionNotifiers.clear(); | 444 m_pendingForPermissionNotifiers.clear(); |
| 445 return; | 445 return; |
| 446 } | 446 } |
| 447 | 447 |
| 448 if (!isAllowed()) { | 448 if (!isAllowed()) { |
| 449 RefPtr<PositionError> error = PositionError::create(PositionError::PERMI
SSION_DENIED, ASCIILiteral(permissionDeniedErrorMessage)); | 449 RefPtr<PositionError> error = PositionError::create(PositionError::PERMI
SSION_DENIED, ASCIILiteral(permissionDeniedErrorMessage)); |
| 450 error->setIsFatal(true); | 450 error->setIsFatal(true); |
| 451 handleError(error.get()); | 451 handleError(error.get()); |
| 452 m_requestsAwaitingCachedPosition.clear(); | 452 m_requestsAwaitingCachedPosition.clear(); |
| 453 return; | 453 return; |
| 454 } | 454 } |
| 455 | 455 |
| 456 // If the service has a last position, use it to call back for all requests. | 456 // If the service has a last position, use it to call back for all requests. |
| 457 // If any of the requests are waiting for permission for a cached position, | 457 // If any of the requests are waiting for permission for a cached position, |
| 458 // the position from the service will be at least as fresh. | 458 // the position from the service will be at least as fresh. |
| 459 if (lastPosition()) | 459 if (lastPosition()) |
| 460 makeSuccessCallbacks(); | 460 makeSuccessCallbacks(); |
| 461 else | 461 else |
| 462 makeCachedPositionCallbacks(); | 462 makeCachedPositionCallbacks(); |
| 463 } | 463 } |
| 464 | 464 |
| 465 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) | 465 void Geolocation::sendError(GeoNotifierVector& notifiers, PositionError* error) |
| 466 { | 466 { |
| 467 GeoNotifierVector::const_iterator end = notifiers.end(); | 467 GeoNotifierVector::const_iterator end = notifiers.end(); |
| 468 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; +
+it) { | 468 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; +
+it) { |
| 469 RefPtr<GeoNotifier> notifier = *it; | 469 RefPtr<GeoNotifier> notifier = *it; |
| 470 | 470 |
| 471 notifier->runErrorCallback(error); | 471 notifier->runErrorCallback(error); |
| 472 } | 472 } |
| 473 } | 473 } |
| 474 | 474 |
| 475 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi
on) | 475 void Geolocation::sendPosition(GeoNotifierVector& notifiers, Geoposition* positi
on) |
| 476 { | 476 { |
| 477 GeoNotifierVector::const_iterator end = notifiers.end(); | 477 GeoNotifierVector::const_iterator end = notifiers.end(); |
| 478 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++
it) | 478 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++
it) |
| 479 (*it)->runSuccessCallback(position); | 479 (*it)->runSuccessCallback(position); |
| 480 } | 480 } |
| 481 | 481 |
| 482 void Geolocation::stopTimer(GeoNotifierVector& notifiers) | 482 void Geolocation::stopTimer(GeoNotifierVector& notifiers) |
| 483 { | 483 { |
| 484 GeoNotifierVector::const_iterator end = notifiers.end(); | 484 GeoNotifierVector::const_iterator end = notifiers.end(); |
| 485 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++
it) | 485 for (GeoNotifierVector::const_iterator it = notifiers.begin(); it != end; ++
it) |
| 486 (*it)->stopTimer(); | 486 (*it)->stopTimer(); |
| 487 } | 487 } |
| 488 | 488 |
| 489 void Geolocation::stopTimersForOneShots() | 489 void Geolocation::stopTimersForOneShots() |
| 490 { | 490 { |
| 491 GeoNotifierVector copy; | 491 GeoNotifierVector copy; |
| 492 copyToVector(m_oneShots, copy); | 492 copyToVector(m_oneShots, copy); |
| 493 | 493 |
| 494 stopTimer(copy); | 494 stopTimer(copy); |
| 495 } | 495 } |
| 496 | 496 |
| 497 void Geolocation::stopTimersForWatchers() | 497 void Geolocation::stopTimersForWatchers() |
| 498 { | 498 { |
| 499 GeoNotifierVector copy; | 499 GeoNotifierVector copy; |
| 500 m_watchers.getNotifiersVector(copy); | 500 m_watchers.getNotifiersVector(copy); |
| 501 | 501 |
| 502 stopTimer(copy); | 502 stopTimer(copy); |
| 503 } | 503 } |
| 504 | 504 |
| 505 void Geolocation::stopTimers() | 505 void Geolocation::stopTimers() |
| 506 { | 506 { |
| 507 stopTimersForOneShots(); | 507 stopTimersForOneShots(); |
| 508 stopTimersForWatchers(); | 508 stopTimersForWatchers(); |
| 509 } | 509 } |
| 510 | 510 |
| 511 void Geolocation::cancelRequests(GeoNotifierVector& notifiers) | 511 void Geolocation::cancelRequests(GeoNotifierVector& notifiers) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 GeoNotifierVector::const_iterator end = src.end(); | 544 GeoNotifierVector::const_iterator end = src.end(); |
| 545 for (GeoNotifierVector::const_iterator it = src.begin(); it != end; ++it) { | 545 for (GeoNotifierVector::const_iterator it = src.begin(); it != end; ++it) { |
| 546 GeoNotifier* notifier = it->get(); | 546 GeoNotifier* notifier = it->get(); |
| 547 dest.add(notifier); | 547 dest.add(notifier); |
| 548 } | 548 } |
| 549 } | 549 } |
| 550 | 550 |
| 551 void Geolocation::handleError(PositionError* error) | 551 void Geolocation::handleError(PositionError* error) |
| 552 { | 552 { |
| 553 ASSERT(error); | 553 ASSERT(error); |
| 554 | 554 |
| 555 GeoNotifierVector oneShotsCopy; | 555 GeoNotifierVector oneShotsCopy; |
| 556 copyToVector(m_oneShots, oneShotsCopy); | 556 copyToVector(m_oneShots, oneShotsCopy); |
| 557 | 557 |
| 558 GeoNotifierVector watchersCopy; | 558 GeoNotifierVector watchersCopy; |
| 559 m_watchers.getNotifiersVector(watchersCopy); | 559 m_watchers.getNotifiersVector(watchersCopy); |
| 560 | 560 |
| 561 // Clear the lists before we make the callbacks, to avoid clearing notifiers | 561 // Clear the lists before we make the callbacks, to avoid clearing notifiers |
| 562 // added by calls to Geolocation methods from the callbacks, and to prevent | 562 // added by calls to Geolocation methods from the callbacks, and to prevent |
| 563 // further callbacks to these notifiers. | 563 // further callbacks to these notifiers. |
| 564 GeoNotifierVector oneShotsWithCachedPosition; | 564 GeoNotifierVector oneShotsWithCachedPosition; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 m_allowGeolocation = InProgress; | 596 m_allowGeolocation = InProgress; |
| 597 | 597 |
| 598 // Ask the embedder: it maintains the geolocation challenge policy itself. | 598 // Ask the embedder: it maintains the geolocation challenge policy itself. |
| 599 GeolocationController::from(page)->requestPermission(this); | 599 GeolocationController::from(page)->requestPermission(this); |
| 600 } | 600 } |
| 601 | 601 |
| 602 void Geolocation::makeSuccessCallbacks() | 602 void Geolocation::makeSuccessCallbacks() |
| 603 { | 603 { |
| 604 ASSERT(lastPosition()); | 604 ASSERT(lastPosition()); |
| 605 ASSERT(isAllowed()); | 605 ASSERT(isAllowed()); |
| 606 | 606 |
| 607 GeoNotifierVector oneShotsCopy; | 607 GeoNotifierVector oneShotsCopy; |
| 608 copyToVector(m_oneShots, oneShotsCopy); | 608 copyToVector(m_oneShots, oneShotsCopy); |
| 609 | 609 |
| 610 GeoNotifierVector watchersCopy; | 610 GeoNotifierVector watchersCopy; |
| 611 m_watchers.getNotifiersVector(watchersCopy); | 611 m_watchers.getNotifiersVector(watchersCopy); |
| 612 | 612 |
| 613 // Clear the lists before we make the callbacks, to avoid clearing notifiers | 613 // Clear the lists before we make the callbacks, to avoid clearing notifiers |
| 614 // added by calls to Geolocation methods from the callbacks, and to prevent | 614 // added by calls to Geolocation methods from the callbacks, and to prevent |
| 615 // further callbacks to these notifiers. | 615 // further callbacks to these notifiers. |
| 616 m_oneShots.clear(); | 616 m_oneShots.clear(); |
| 617 | 617 |
| 618 sendPosition(oneShotsCopy, lastPosition()); | 618 sendPosition(oneShotsCopy, lastPosition()); |
| 619 sendPosition(watchersCopy, lastPosition()); | 619 sendPosition(watchersCopy, lastPosition()); |
| 620 | 620 |
| 621 if (!hasListeners()) | 621 if (!hasListeners()) |
| 622 stopUpdating(); | 622 stopUpdating(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 652 { | 652 { |
| 653 Page* page = this->page(); | 653 Page* page = this->page(); |
| 654 if (!page) | 654 if (!page) |
| 655 return; | 655 return; |
| 656 | 656 |
| 657 GeolocationController::from(page)->removeObserver(this); | 657 GeolocationController::from(page)->removeObserver(this); |
| 658 } | 658 } |
| 659 | 659 |
| 660 void Geolocation::handlePendingPermissionNotifiers() | 660 void Geolocation::handlePendingPermissionNotifiers() |
| 661 { | 661 { |
| 662 // While we iterate through the list, we need not worry about list being mod
ified as the permission | 662 // While we iterate through the list, we need not worry about list being mod
ified as the permission |
| 663 // is already set to Yes/No and no new listeners will be added to the pendin
g list | 663 // is already set to Yes/No and no new listeners will be added to the pendin
g list |
| 664 GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end(); | 664 GeoNotifierSet::const_iterator end = m_pendingForPermissionNotifiers.end(); |
| 665 for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.b
egin(); iter != end; ++iter) { | 665 for (GeoNotifierSet::const_iterator iter = m_pendingForPermissionNotifiers.b
egin(); iter != end; ++iter) { |
| 666 GeoNotifier* notifier = iter->get(); | 666 GeoNotifier* notifier = iter->get(); |
| 667 | 667 |
| 668 if (isAllowed()) { | 668 if (isAllowed()) { |
| 669 // start all pending notification requests as permission granted. | 669 // start all pending notification requests as permission granted. |
| 670 // The notifier is always ref'ed by m_oneShots or m_watchers. | 670 // The notifier is always ref'ed by m_oneShots or m_watchers. |
| 671 if (startUpdating(notifier)) | 671 if (startUpdating(notifier)) |
| 672 notifier->startTimerIfNeeded(); | 672 notifier->startTimerIfNeeded(); |
| 673 else | 673 else |
| 674 notifier->setFatalError(PositionError::create(PositionError::POS
ITION_UNAVAILABLE, ASCIILiteral(failedToStartServiceErrorMessage))); | 674 notifier->setFatalError(PositionError::create(PositionError::POS
ITION_UNAVAILABLE, ASCIILiteral(failedToStartServiceErrorMessage))); |
| 675 } else | 675 } else |
| 676 notifier->setFatalError(PositionError::create(PositionError::PERMISS
ION_DENIED, ASCIILiteral(permissionDeniedErrorMessage))); | 676 notifier->setFatalError(PositionError::create(PositionError::PERMISS
ION_DENIED, ASCIILiteral(permissionDeniedErrorMessage))); |
| 677 } | 677 } |
| 678 } | 678 } |
| 679 | 679 |
| 680 } // namespace WebCore | 680 } // namespace WebCore |
| OLD | NEW |