WebCore:
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Mar 2009 01:47:14 +0000 (01:47 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Mar 2009 01:47:14 +0000 (01:47 +0000)
2009-03-02  Sam Weinig  <sam@webkit.org>

        Reviewed by Geoffrey Garen.

        Fix for <rdar://problem/6507404> Add Geolocation support.

        This is not yet turned on for any Mac platform.

        * WebCore.xcodeproj/project.pbxproj:
        * page/Chrome.cpp:
        (WebCore::Chrome::shouldAllowGeolocationForFrame):
        * page/Chrome.h:
        * page/ChromeClient.h:
        (WebCore::ChromeClient::shouldAllowGeolocationForFrame):
        * page/Geolocation.cpp:
        (WebCore::Geolocation::Geolocation):
        (WebCore::Geolocation::disconnectFrame): Remove call to setUsingGeolocation as the document
        will not be alive at this point.
        (WebCore::Geolocation::getCurrentPosition): Check if the embedding app allows geolocation and
        return a PERMISSION_DENIED if not.
        (WebCore::Geolocation::watchPosition): Ditto.
        (WebCore::Geolocation::shouldAllowGeolocation): Perform request to embedding layer of whether
        to allow geolocation and cache the result.
        * page/Geolocation.h:
        (WebCore::Geolocation::):
        * platform/GeolocationService.cpp:
        * platform/GeolocationService.h:
        (WebCore::GeolocationService::~GeolocationService):
        (WebCore::GeolocationService::stopUpdating):
        * platform/mac/GeolocationServiceMac.h: Added.
        (WebCore::GeolocationServiceMac::lastPosition):
        (WebCore::GeolocationServiceMac::lastError):
        * platform/mac/GeolocationServiceMac.mm: Added.
        (WebCore::GeolocationService::create):
        (WebCore::GeolocationServiceMac::GeolocationServiceMac):
        (WebCore::GeolocationServiceMac::~GeolocationServiceMac):
        (WebCore::GeolocationServiceMac::startUpdating):
        (WebCore::GeolocationServiceMac::stopUpdating):
        (WebCore::GeolocationServiceMac::suspend):
        (WebCore::GeolocationServiceMac::resume):
        (WebCore::GeolocationServiceMac::positionChanged):
        (WebCore::GeolocationServiceMac::errorOccurred):
        (-[WebCoreCoreLocationObserver initWithCallback:]):
        (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
        (-[WebCoreCoreLocationObserver locationManager:didFailWithError:]):

WebKit/mac:

2009-03-02  Sam Weinig  <sam@webkit.org>

        Reviewed by Geoffrey Garen.

        Fix for <rdar://problem/6507404> Add Geolocation support.

        This is not yet turned on for any Mac platform.

        Add SPI to ask the embedding application whether to allow
        Geolocation for an origin.

        * WebCoreSupport/WebChromeClient.h:
        * WebCoreSupport/WebChromeClient.mm:
        (WebChromeClient::shouldAllowGeolocationForFrame):
        * WebView/WebUIDelegatePrivate.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41375 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/page/Chrome.cpp
WebCore/page/Chrome.h
WebCore/page/ChromeClient.h
WebCore/page/Geolocation.cpp
WebCore/page/Geolocation.h
WebCore/platform/GeolocationService.cpp
WebCore/platform/GeolocationService.h
WebCore/platform/mac/GeolocationServiceMac.h [new file with mode: 0644]
WebCore/platform/mac/GeolocationServiceMac.mm [new file with mode: 0644]
WebKit/mac/ChangeLog
WebKit/mac/WebCoreSupport/WebChromeClient.h
WebKit/mac/WebCoreSupport/WebChromeClient.mm
WebKit/mac/WebView/WebUIDelegatePrivate.h

index 51a9d8e5f4c6f2f4b59a8ef25ef72115324577db..a5b4bd479b7d6bc004dd8dc76b44645d56d4e865 100644 (file)
@@ -1,3 +1,49 @@
+2009-03-02  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Geoffrey Garen.
+
+        Fix for <rdar://problem/6507404> Add Geolocation support.
+
+        This is not yet turned on for any Mac platform.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/Chrome.cpp:
+        (WebCore::Chrome::shouldAllowGeolocationForFrame):
+        * page/Chrome.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::shouldAllowGeolocationForFrame):
+        * page/Geolocation.cpp:
+        (WebCore::Geolocation::Geolocation):
+        (WebCore::Geolocation::disconnectFrame): Remove call to setUsingGeolocation as the document
+        will not be alive at this point.
+        (WebCore::Geolocation::getCurrentPosition): Check if the embedding app allows geolocation and
+        return a PERMISSION_DENIED if not.
+        (WebCore::Geolocation::watchPosition): Ditto.
+        (WebCore::Geolocation::shouldAllowGeolocation): Perform request to embedding layer of whether
+        to allow geolocation and cache the result. 
+        * page/Geolocation.h:
+        (WebCore::Geolocation::):
+        * platform/GeolocationService.cpp:
+        * platform/GeolocationService.h:
+        (WebCore::GeolocationService::~GeolocationService):
+        (WebCore::GeolocationService::stopUpdating):
+        * platform/mac/GeolocationServiceMac.h: Added.
+        (WebCore::GeolocationServiceMac::lastPosition):
+        (WebCore::GeolocationServiceMac::lastError):
+        * platform/mac/GeolocationServiceMac.mm: Added.
+        (WebCore::GeolocationService::create):
+        (WebCore::GeolocationServiceMac::GeolocationServiceMac):
+        (WebCore::GeolocationServiceMac::~GeolocationServiceMac):
+        (WebCore::GeolocationServiceMac::startUpdating):
+        (WebCore::GeolocationServiceMac::stopUpdating):
+        (WebCore::GeolocationServiceMac::suspend):
+        (WebCore::GeolocationServiceMac::resume):
+        (WebCore::GeolocationServiceMac::positionChanged):
+        (WebCore::GeolocationServiceMac::errorOccurred):
+        (-[WebCoreCoreLocationObserver initWithCallback:]):
+        (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
+        (-[WebCoreCoreLocationObserver locationManager:didFailWithError:]):
+
 2009-03-02  Kevin Ollivier  <kevino@theolliviers.com>
 
         Build fixes for wxWidgets Mac trunk build.
index aa8df29717d98cd5e1516567902a2bc4afc9686a..620548e87f5f6cfcf38b819d5877b775ad76f123 100644 (file)
                BCE1C4400D9830F4003B02F2 /* JSLocationCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */; };
                BCE3BEC20D222B1D007E06E4 /* TagNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE3BEC00D222B1D007E06E4 /* TagNodeList.cpp */; };
                BCE3BEC30D222B1D007E06E4 /* TagNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE3BEC10D222B1D007E06E4 /* TagNodeList.h */; };
+               BCE494AB0F4F5E9E0084E319 /* GeolocationServiceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */; settings = {ATTRIBUTES = (); }; };
+               BCE494AC0F4F5E9E0084E319 /* GeolocationServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */; };
                BCE658FF0EA9248A007E4533 /* Theme.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE658FE0EA9248A007E4533 /* Theme.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCE659A90EA927B9007E4533 /* ThemeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE659A80EA927B9007E4533 /* ThemeTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCE659E60EA92FB2007E4533 /* ThemeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE659E50EA92FB2007E4533 /* ThemeMac.h */; };
                FE80DA710E9C472F000D6F75 /* JSPositionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */; };
                FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
                FEAB90120EA51B9C006348C3 /* GeolocationService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEAB90100EA51B9C006348C3 /* GeolocationService.cpp */; };
-               FEAB90130EA51B9C006348C3 /* GeolocationService.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAB90110EA51B9C006348C3 /* GeolocationService.h */; };
+               FEAB90130EA51B9C006348C3 /* GeolocationService.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAB90110EA51B9C006348C3 /* GeolocationService.h */; settings = {ATTRIBUTES = (); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLocationCustom.cpp; sourceTree = "<group>"; };
                BCE3BEC00D222B1D007E06E4 /* TagNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagNodeList.cpp; sourceTree = "<group>"; };
                BCE3BEC10D222B1D007E06E4 /* TagNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagNodeList.h; sourceTree = "<group>"; };
+               BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeolocationServiceMac.h; sourceTree = "<group>"; };
+               BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GeolocationServiceMac.mm; sourceTree = "<group>"; };
                BCE658FE0EA9248A007E4533 /* Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Theme.h; sourceTree = "<group>"; };
                BCE659A80EA927B9007E4533 /* ThemeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeTypes.h; sourceTree = "<group>"; };
                BCE659E50EA92FB2007E4533 /* ThemeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeMac.h; sourceTree = "<group>"; };
                                066C772C0AB603D200238CC4 /* FileChooserMac.mm */,
                                514B3F750C722055000530DF /* FileSystemMac.mm */,
                                935C476C09AC4D6300A6AAB4 /* FoundationExtras.h */,
-                               6593923909AE435C002C531F /* KURLMac.mm */,
+                               BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */,
+                               BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */,
                                935C476E09AC4D7300A6AAB4 /* KeyEventMac.mm */,
+                               6593923909AE435C002C531F /* KURLMac.mm */,
                                9352084409BD43B900F2038D /* Language.mm */,
                                06E81ED60AB5D5E900C87837 /* LocalCurrentGraphicsContext.h */,
                                06E81EEB0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm */,
                                BC94D1070C274F88006BC617 /* PlatformScreenMac.mm */,
                                0668E18E0ADD9640004128E0 /* PopupMenuMac.mm */,
                                E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */,
-                               84B2B24F056BF15F00D2B771 /* SSLKeyGeneratorMac.mm */,
                                1CE24F960D7CAF0E007E04C2 /* SchedulePairMac.mm */,
-                               9353676A09AED88B00D35CD6 /* ScrollViewMac.mm */,
                                BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */,
                                BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */,
                                BCEF869E0E844E9D00A85CD5 /* ScrollbarThemeMac.mm */,
+                               9353676A09AED88B00D35CD6 /* ScrollViewMac.mm */,
                                AB71709F0B31193B0017123E /* SearchPopupMenuMac.mm */,
                                1A4A95510B4EDCFF002D8C3C /* SharedBufferMac.mm */,
                                93309E9F099EB78C0056E581 /* SharedTimerMac.mm */,
                                0A4844980CA44CB200B7BD48 /* SoftLinking.h */,
                                4B3043C80AE0371D00A82647 /* SoundMac.mm */,
+                               84B2B24F056BF15F00D2B771 /* SSLKeyGeneratorMac.mm */,
                                6582A15509999D6D00BEEB6D /* SystemTimeMac.cpp */,
                                BCE659E50EA92FB2007E4533 /* ThemeMac.h */,
                                BCE659E80EA92FFA007E4533 /* ThemeMac.mm */,
                                1A569D230D7E2B82007C3983 /* runtime_object.h in Headers */,
                                1A569D250D7E2B82007C3983 /* runtime_root.h in Headers */,
                                93309E1E099E64920056E581 /* visible_units.h in Headers */,
+                               BCE494AB0F4F5E9E0084E319 /* GeolocationServiceMac.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1A569D220D7E2B82007C3983 /* runtime_object.cpp in Sources */,
                                1A569D240D7E2B82007C3983 /* runtime_root.cpp in Sources */,
                                93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
+                               BCE494AC0F4F5E9E0084E319 /* GeolocationServiceMac.mm in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index fd7bc1a4df813ea069270f78b87edc94eae2335d..f3a0c40310d30e26a34304cae669bd88f021234a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
@@ -387,6 +387,16 @@ void Chrome::enableSuddenTermination()
     m_client->enableSuddenTermination();
 }
 
+bool Chrome::shouldAllowGeolocationForFrame(Frame* frame)
+{
+    // Defer loads in case the client method runs a new event loop that would 
+    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
+    PageGroupLoadDeferrer deferrer(m_page, true);
+
+    ASSERT(frame);
+    return m_client->shouldAllowGeolocationForFrame(frame);
+}
+
 void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
 {
     m_client->runOpenPanel(frame, fileChooser);
index 47b912d28c1bccaa2d8c3790219db44c0373deac..bb265e5d2d2e9962a392ff0db222532bc1355bc7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -119,6 +119,8 @@ namespace WebCore {
         void enableSuddenTermination();
         void disableSuddenTermination();
 
+        bool shouldAllowGeolocationForFrame(Frame*);
+
         void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
 
 #if PLATFORM(MAC)
index aa9b32906e5e150fed271d1c394db09f587b98b0..5a771eb905352923b980eb9bc8b89464f07b8af1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple, Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -48,7 +48,7 @@ namespace WebCore {
     class Page;
     class String;
     class Widget;
-    
+
     struct FrameLoadRequest;
     struct WindowFeatures;
 
@@ -152,6 +152,8 @@ namespace WebCore {
                                           float value, float proportion, ScrollbarControlPartMask);
         virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
 
+        virtual bool shouldAllowGeolocationForFrame(Frame*) { return false; }
+
         virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
 
         // Notification that the given form element has changed. This function
index 4fc5bd034b188a610d74eb8c02ac5507f5c8380a..a05813c15b657a7fbde0aaa5e8cb9d166f69c038 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "Geolocation.h"
 
+#include "Chrome.h"
 #include "Document.h"
 #include "Frame.h"
+#include "Page.h"
 #include "PositionError.h"
 
 namespace WebCore {
@@ -54,6 +56,7 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
 Geolocation::Geolocation(Frame* frame)
     : m_frame(frame)
     , m_service(GeolocationService::create(this))
+    , m_allowGeolocation(Unknown)
 {
     ASSERT(m_frame->document());
     m_frame->document()->setUsingGeolocation(true);
@@ -62,7 +65,6 @@ Geolocation::Geolocation(Frame* frame)
 void Geolocation::disconnectFrame()
 {
     m_service->stopUpdating();
-    m_frame->document()->setUsingGeolocation(false);
     m_frame = 0;
 }
 
@@ -70,6 +72,14 @@ void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallbac
 {
     RefPtr<GeoNotifier> notifier = GeoNotifier::create(successCallback, errorCallback, options);
 
+    if (!shouldAllowGeolocation()) {
+        if (notifier->m_errorCallback) {
+            RefPtr<PositionError> error = WebCore::PositionError::create(PositionError::PERMISSION_DENIED, "Disallowed Geolocation");
+            notifier->m_errorCallback->handleEvent(error.get());
+        }
+        return;
+    }
+
     if (!m_service->startUpdating(options)) {
         if (notifier->m_errorCallback) {
             RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
@@ -85,6 +95,14 @@ int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, Pas
 {
     RefPtr<GeoNotifier> notifier = GeoNotifier::create(successCallback, errorCallback, options);
 
+    if (!shouldAllowGeolocation()) {
+        if (notifier->m_errorCallback) {
+            RefPtr<PositionError> error = WebCore::PositionError::create(PositionError::PERMISSION_DENIED, "Disallowed Geolocation");
+            notifier->m_errorCallback->handleEvent(error.get());
+        }
+        return 0;
+    }
+
     if (!m_service->startUpdating(options)) {
         if (notifier->m_errorCallback) {
             RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
@@ -218,4 +236,18 @@ void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service)
     handleError(service->lastError());
 }
 
+bool Geolocation::shouldAllowGeolocation()
+{
+    if (!m_frame)
+        return false;
+
+    Page* page = m_frame->page();
+    if (!page)
+        return false;
+
+    if (m_allowGeolocation == Unknown)
+        m_allowGeolocation = page->chrome()->shouldAllowGeolocationForFrame(m_frame) ? Yes : No;
+    return m_allowGeolocation == Yes;
+}
+
 } // namespace WebCore
index 572cbd886d24f9fe377f6cf98ce7b5c548e59e49..0a5bf8350296ab7ab502e32424fdb7efc8061c30 100644 (file)
@@ -77,7 +77,7 @@ private:
     private:
         GeoNotifier(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PositionOptions*);
     };
-    
+
     bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
 
     void sendErrorToOneShots(PositionError*);
@@ -86,10 +86,13 @@ private:
     void sendPositionToWatchers(Geoposition*);
     
     void handleError(PositionError*);
-    
+
+    // GeolocationServiceClient
     virtual void geolocationServicePositionChanged(GeolocationService*);
     virtual void geolocationServiceErrorOccurred(GeolocationService*);
-            
+
+    bool shouldAllowGeolocation();
+
     typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
     typedef HashMap<int, RefPtr<GeoNotifier> > GeoNotifierMap;
     
@@ -97,6 +100,12 @@ private:
     GeoNotifierMap m_watchers;
     Frame* m_frame;
     OwnPtr<GeolocationService> m_service;
+
+    enum {
+        Unknown,
+        Yes,
+        No
+    } m_allowGeolocation;
 };
     
 } // namespace WebCore
index dfd5a5cdc607622e04008d9b0d9a8f47c3d8e183..9b362c8ccb5bd1d7bd32ce40bdc7775dbe8af988 100644 (file)
@@ -26,9 +26,7 @@
 #include "config.h"
 #include "GeolocationService.h"
 
-#include "Geoposition.h"
-#include "PositionError.h"
-#include "PositionOptions.h"
+#include <wtf/Assertions.h>
 
 namespace WebCore {
 
index 90d52eb502461a53d2c52248fbde026336faec9c..74a6eade47b8e709a7ebaed56765daf08fa1df4f 100644 (file)
@@ -38,21 +38,21 @@ class PositionOptions;
 class GeolocationServiceClient {
 public:
     virtual ~GeolocationServiceClient() { }
-    virtual void geolocationServicePositionChanged(GeolocationService*) { }
-    virtual void geolocationServiceErrorOccurred(GeolocationService*) { }
+    virtual void geolocationServicePositionChanged(GeolocationService*) = 0;
+    virtual void geolocationServiceErrorOccurred(GeolocationService*) = 0;
 };
 
 class GeolocationService : public Noncopyable {
 public:
     static GeolocationService* create(GeolocationServiceClient*);
-    virtual ~GeolocationService() {}
+    virtual ~GeolocationService() { }
     
     virtual bool startUpdating(PositionOptions*) { return false; }
-    virtual void stopUpdating() {}
+    virtual void stopUpdating() { }
     
     virtual void suspend() { }
     virtual void resume() { }
-    
+
     virtual Geoposition* lastPosition() const { return 0; }
     virtual PositionError* lastError() const { return 0; }
 
@@ -65,7 +65,7 @@ protected:
 private:
     GeolocationServiceClient* m_geolocationServiceClient;
 };
-    
+
 } // namespace WebCore
 
 #endif // GeolocationService_h
diff --git a/WebCore/platform/mac/GeolocationServiceMac.h b/WebCore/platform/mac/GeolocationServiceMac.h
new file mode 100644 (file)
index 0000000..d0342e7
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef GeolocationServiceMac_h
+#define GeolocationServiceMac_h
+
+#if ENABLE(GEOLOCATION)
+
+#include "GeolocationService.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+
+#ifdef __OBJC__
+@class CLLocationManager;
+@class WebCoreCoreLocationObserver;
+#else
+class CLLocationManager;
+class WebCoreCoreLocationObserver;
+#endif
+
+namespace WebCore {
+
+class GeolocationServiceMac : public GeolocationService {
+public:
+    GeolocationServiceMac(GeolocationServiceClient*);
+    virtual ~GeolocationServiceMac();
+    
+    virtual bool startUpdating(PositionOptions*);
+    virtual void stopUpdating();
+
+    virtual void suspend();
+    virtual void resume();
+
+    virtual Geoposition* lastPosition() const { return m_lastPosition.get(); }
+    virtual PositionError* lastError() const { return m_lastError.get(); }
+
+    void positionChanged(PassRefPtr<Geoposition>);
+    void errorOccurred(PassRefPtr<PositionError>);
+
+private:
+    RetainPtr<CLLocationManager> m_locationManager;
+    RetainPtr<WebCoreCoreLocationObserver> m_objcObserver;
+    
+    RefPtr<Geoposition> m_lastPosition;
+    RefPtr<PositionError> m_lastError;
+};
+    
+} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
+
+#endif // GeolocationServiceMac_h
diff --git a/WebCore/platform/mac/GeolocationServiceMac.mm b/WebCore/platform/mac/GeolocationServiceMac.mm
new file mode 100644 (file)
index 0000000..cbf6708
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#import "config.h"
+
+#if ENABLE(GEOLOCATION)
+
+#import "GeolocationServiceMac.h"
+
+#import "Geoposition.h"
+#import "PositionError.h"
+#import "PositionOptions.h"
+#import "SoftLinking.h"
+#import <CoreLocation/CoreLocation.h>
+#import <objc/objc-runtime.h>
+#import <wtf/RefPtr.h>
+#import <wtf/UnusedParam.h>
+
+SOFT_LINK_FRAMEWORK(CoreLocation)
+
+SOFT_LINK_CLASS(CoreLocation, CLLocationManager)
+SOFT_LINK_CLASS(CoreLocation, CLLocation)
+
+SOFT_LINK_CONSTANT(CoreLocation, kCLLocationAccuracyBest, double)
+SOFT_LINK_CONSTANT(CoreLocation, kCLLocationAccuracyHundredMeters, double)
+
+#define kCLLocationAccuracyBest getkCLLocationAccuracyBest()
+#define kCLLocationAccuracyHundredMeters getkCLLocationAccuracyHundredMeters()
+
+using namespace WebCore;
+
+@interface WebCoreCoreLocationObserver : NSObject<CLLocationManagerDelegate>
+{
+    GeolocationServiceMac* m_callback;
+}
+
+- (id)initWithCallback:(GeolocationServiceMac*)callback;
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
+
+@end
+
+namespace WebCore {
+
+GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+{
+    return new GeolocationServiceMac(client);
+}
+
+GeolocationServiceMac::GeolocationServiceMac(GeolocationServiceClient* client)
+    : GeolocationService(client)
+    , m_objcObserver(AdoptNS, [[WebCoreCoreLocationObserver alloc] initWithCallback:this])
+{
+}
+
+GeolocationServiceMac::~GeolocationServiceMac()
+{
+    [m_locationManager.get() stopUpdatingLocation];
+    m_locationManager.get().delegate = nil;
+}
+
+bool GeolocationServiceMac::startUpdating(PositionOptions* options)
+{
+    #define CLLocationManager getCLLocationManagerClass()
+    if (!m_locationManager.get()) {
+        m_locationManager.adoptNS([[CLLocationManager alloc] init]);
+        m_locationManager.get().delegate = m_objcObserver.get();
+    }
+
+    if (!m_locationManager.get().locationServicesEnabled)
+        return false;
+
+    if (options) {
+        // CLLocationAccuracy values suggested by Ron Huang.
+        CLLocationAccuracy accuracy = options->enableHighAccuracy() ? kCLLocationAccuracyBest : kCLLocationAccuracyHundredMeters;
+        m_locationManager.get().desiredAccuracy = accuracy;
+    }
+    
+    // This can safely be called multiple times.
+    [m_locationManager.get() startUpdatingLocation];
+    
+    return true;
+    #undef CLLocationManager
+}
+
+void GeolocationServiceMac::stopUpdating()
+{
+    [m_locationManager.get() stopUpdatingLocation];
+}
+
+void GeolocationServiceMac::suspend()
+{
+    [m_locationManager.get() stopUpdatingLocation];
+}
+
+void GeolocationServiceMac::resume()
+{
+    [m_locationManager.get() startUpdatingLocation];
+}
+
+void GeolocationServiceMac::positionChanged(PassRefPtr<Geoposition> position)
+{
+    m_lastPosition = position;
+    GeolocationService::positionChanged();
+}
+    
+void GeolocationServiceMac::errorOccurred(PassRefPtr<PositionError> error)
+{
+    m_lastError = error;
+    GeolocationService::errorOccurred();
+}
+
+} // namespace WebCore
+
+@implementation WebCoreCoreLocationObserver
+
+- (id)initWithCallback:(GeolocationServiceMac *)callback
+{
+    self = [super init];
+    if (self)
+        m_callback = callback;
+    return self;
+}
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
+{
+    ASSERT(m_callback);
+    ASSERT(newLocation);
+    UNUSED_PARAM(manager);
+    UNUSED_PARAM(oldLocation);
+
+    // Normalize
+    double altitude = newLocation.altitude;
+    double altitudeAccuracy = newLocation.verticalAccuracy;
+    if (altitudeAccuracy < 0.0) {
+        altitudeAccuracy = 0.0;
+        altitude = 0.0;
+    }
+    
+    WTF::RefPtr<WebCore::Geoposition> newPosition = WebCore::Geoposition::create(
+                             newLocation.coordinate.latitude,
+                             newLocation.coordinate.longitude,
+                             altitude,
+                             newLocation.horizontalAccuracy,
+                             altitudeAccuracy,
+                             newLocation.course,
+                             newLocation.speed,
+                             [newLocation.timestamp timeIntervalSinceReferenceDate] * 1000.0); // seconds -> milliseconds
+    
+    m_callback->positionChanged(newPosition.release());
+}
+
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
+{
+    ASSERT(m_callback);
+    ASSERT(error);
+    UNUSED_PARAM(manager);
+
+    PositionError::ErrorCode code;
+    switch ([error code]) {
+        case kCLErrorDenied:
+            code = PositionError::PERMISSION_DENIED;
+        case kCLErrorLocationUnknown:
+            code = PositionError::POSITION_UNAVAILABLE;
+        default:
+            code = PositionError::POSITION_UNAVAILABLE;
+    }
+
+    m_callback->errorOccurred(PositionError::create(code, [error localizedDescription]));
+}
+
+@end
+
+#endif // ENABLE(GEOLOCATION)
index 9103da1507870202ddbb77ae5b9c90d1d5226519..889c73505d3276dc2d50b82f2519de179f48ae62 100644 (file)
@@ -1,3 +1,19 @@
+2009-03-02  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Geoffrey Garen.
+
+        Fix for <rdar://problem/6507404> Add Geolocation support.
+
+        This is not yet turned on for any Mac platform.
+
+        Add SPI to ask the embedding application whether to allow
+        Geolocation for an origin.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::shouldAllowGeolocationForFrame):
+        * WebView/WebUIDelegatePrivate.h:
+
 2009-03-02  Anders Carlsson  <andersca@apple.com>
 
         Fix PowerPC build.
index 21b5a5897c05badac847eeb30ffaafcc04f015fb..24bddf769f132f8c0cdd3e87c1c8e8f2db6ac2b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -140,6 +140,8 @@ public:
     virtual void setNeedsOneShotDrawingSynchronization();
 #endif
 
+    virtual bool shouldAllowGeolocationForFrame(WebCore::Frame*);
+
 private:
     WebView *m_webView;
 };
index b5a7543b24597bb0eff34e3d78554e879b98eb69..8e9cd8a1fc81728725d6cd2760349668b578cddd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -664,6 +664,21 @@ void WebChromeClient::setNeedsOneShotDrawingSynchronization()
 }
 #endif
 
+bool WebChromeClient::shouldAllowGeolocationForFrame(Frame* frame)
+{
+    BOOL result = NO;
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOrigin:frame->document()->securityOrigin()];
+    result = CallUIDelegateReturningBoolean(NO, m_webView, @selector(webView:shouldAllowLocationServicesForFrame:securityOrigin:), kit(frame), webOrigin);
+    [webOrigin release];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return result;
+}
+
 @implementation WebOpenPanelResultListener
 
 - (id)initWithChooser:(PassRefPtr<FileChooser>)chooser
index bb4d780faee4f0ed4b7395a5deb5be2ad883ae17..6903ff5bfd45cb44810dd9514bcdb560efce9f52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -109,5 +109,7 @@ enum {
 
 - (BOOL)webView:(WebView *)sender shouldReplaceUploadFile:(NSString *)path usingGeneratedFilename:(NSString **)filename;
 - (NSString *)webView:(WebView *)sender generateReplacementFile:(NSString *)path;
+
+- (BOOL)webView:(WebView *)sender shouldAllowLocationServicesForFrame:(WebFrame *)frame securityOrigin:(WebSecurityOrigin *)origin;
+
 @end