Change geolocation provider can monitoring multiple views
authorJihye Kang <jye.kang@samsung.com>
Mon, 19 Aug 2013 11:45:39 +0000 (20:45 +0900)
committerJihye Kang <jye.kang@samsung.com>
Mon, 7 Oct 2013 04:56:25 +0000 (13:56 +0900)
[Title] Change geolocation provider can monitoring multiple views
[Issue#] N/A
[Problem] Crash occurs when positioning view is removed.
[Cause] removed view is referenced.
[Solution] Create one geolocation provider for one context and monitor multiple views so removed view is not referenced.

Change-Id: I02a8eb1a3dd70257f5ef9d9d4896996e7a881bb7

13 files changed:
Source/WebKit2/PlatformTizen.cmake
Source/WebKit2/UIProcess/API/efl/EwkViewImpl.cpp
Source/WebKit2/UIProcess/API/efl/EwkViewImpl.h
Source/WebKit2/UIProcess/API/efl/ewk_context.cpp
Source/WebKit2/UIProcess/API/efl/ewk_context_private.h
Source/WebKit2/UIProcess/API/efl/ewk_geolocation.cpp
Source/WebKit2/UIProcess/API/efl/ewk_geolocation_private.h
Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider.h [moved from Source/WebKit2/UIProcess/API/efl/ewk_view_geolocation_provider.h with 56% similarity]
Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider_private.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
Source/WebKit2/UIProcess/API/efl/ewk_view_geolocation_provider.cpp [deleted file]
Source/WebKit2/UIProcess/API/efl/ewk_view_private.h

index 562f2ec..bbbbde6 100755 (executable)
@@ -84,6 +84,7 @@ LIST(APPEND WebKit2StaticForDebug_SOURCES
     UIProcess/API/efl/ewk_form_data.cpp
     UIProcess/API/efl/ewk_frame.cpp
     UIProcess/API/efl/ewk_geolocation.cpp
+    UIProcess/API/efl/ewk_geolocation_provider.cpp
     UIProcess/API/efl/ewk_history.cpp
     UIProcess/API/efl/ewk_hit_test.cpp
     UIProcess/API/efl/ewk_notification.cpp
@@ -94,7 +95,6 @@ LIST(APPEND WebKit2StaticForDebug_SOURCES
     UIProcess/API/efl/ewk_user_media.cpp
     UIProcess/API/efl/ewk_util.cpp
     UIProcess/API/efl/ewk_view_context_menu_client.cpp
-    UIProcess/API/efl/ewk_view_geolocation_provider.cpp
     UIProcess/API/efl/ewk_view_icondatabase_client.cpp
     UIProcess/API/efl/ewk_view_notification_provider.cpp
     UIProcess/API/efl/ewk_view_tizen_client.cpp
index 5e49e92..1459167 100755 (executable)
@@ -133,7 +133,6 @@ EwkViewImpl::EwkViewImpl(Evas_Object* view)
     , userMediaPermissionRequests(0)
 #endif
 #if ENABLE(TIZEN_GEOLOCATION)
-    , geolocation(0)
     , geolocationPermissionRequests(0)
 #endif
     , suspendRequested(false)
@@ -278,8 +277,6 @@ EwkViewImpl::~EwkViewImpl()
 #endif
 
 #if ENABLE(TIZEN_GEOLOCATION)
-    if (geolocation)
-        ewkGeolocationDeleteGeolocation(geolocation);
     if (geolocationPermissionRequests)
         ewkGeolocationDeletePermissionRequestList(geolocationPermissionRequests);
 #endif
@@ -1399,6 +1396,17 @@ void EwkViewImpl::deleteDataList()
 }
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+bool EwkViewImpl::isValidLocationService()
+{
+    TIZEN_LOGI("geolocation,valid");
+
+    bool valid = true;
+    evas_object_smart_callback_call(m_view, "geolocation,valid", &valid);
+    return valid;
+}
+#endif
+
 #if ENABLE(TIZEN_GESTURE)
 #if ENABLE(TOUCH_EVENTS)
 void EwkViewImpl::feedTouchEventsByType(Ewk_Touch_Event_Type type)
index b96e271..1491f80 100755 (executable)
@@ -312,6 +312,10 @@ public:
     void deleteDataList();
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+    bool isValidLocationService();
+#endif
+
 #if USE(TILED_BACKING_STORE)
     void setScaleFactor(float scaleFactor) { m_scaleFactor = scaleFactor; }
     float scaleFactor() const { return m_scaleFactor; }
@@ -413,7 +417,6 @@ public:
 #endif
 
 #if ENABLE(TIZEN_GEOLOCATION)
-    Ewk_Geolocation* geolocation;
     Eina_List* geolocationPermissionRequests;
 #endif
 
index 77f40d5..6654a7e 100755 (executable)
 void* EflAssistHandle = 0;
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+#include "ewk_geolocation_provider_private.h"
+#endif
+
 using namespace WebCore;
 using namespace WebKit;
 
@@ -242,6 +246,16 @@ PassRefPtr<VibrationProvider> Ewk_Context::vibrationProvider()
 }
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+Ewk_Geolocation_Provider* Ewk_Context::geolocationProvider()
+{
+    if (!m_geolocationProvider)
+        m_geolocationProvider = Ewk_Geolocation_Provider::create(m_context.get());
+
+    return m_geolocationProvider.get();
+}
+#endif
+
 void Ewk_Context::addVisitedLink(const String& visitedURL)
 {
     toImpl(m_context.get())->addVisitedLink(visitedURL);
index 4bb7cf9..3e99fbe 100755 (executable)
@@ -56,6 +56,9 @@ class NetworkInfoProvider;
 #if ENABLE(VIBRATION)
 class VibrationProvider;
 #endif
+#if ENABLE(TIZEN_GEOLOCATION)
+class Ewk_Geolocation_Provider;
+#endif
 
 namespace WebKit {
 class ContextHistoryClientEfl;
@@ -82,6 +85,10 @@ public:
     PassRefPtr<VibrationProvider> vibrationProvider();
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+    Ewk_Geolocation_Provider* geolocationProvider();
+#endif
+
     void addVisitedLink(const String& visitedURL);
 
     void setCacheModel(Ewk_Cache_Model);
@@ -157,6 +164,9 @@ private:
 #if ENABLE(VIBRATION)
     RefPtr<VibrationProvider> m_vibrationProvider;
 #endif
+#if ENABLE(TIZEN_GEOLOCATION)
+    OwnPtr<Ewk_Geolocation_Provider> m_geolocationProvider;
+#endif
     OwnPtr<WebKit::DownloadManagerEfl> m_downloadManager;
     OwnPtr<WebKit::RequestManagerClientEfl> m_requestManagerClient;
 
index a6a80a3..2200f9f 100644 (file)
 
 using namespace WebKit;
 
-struct _Ewk_Geolocation {
-    WKRetainPtr<WKGeolocationManagerRef> geolocationManager;
-    location_manager_h locationManager;
-    bool started;
-};
-
 struct _Ewk_Geolocation_Permission_Request {
     WKRetainPtr<WKGeolocationPermissionRequestRef> requestRef;
     Evas_Object* ewkView;
@@ -64,40 +58,6 @@ struct _Ewk_Geolocation_Permission_Request {
     }
 };
 
-static void ewkGeolocationPositionChangedCallback(double latitude, double longitude, double altitude, time_t timestamp, void* user_data)
-{
-    TIZEN_LOGI("");
-    Ewk_Geolocation* ewkGeolocation = static_cast<Ewk_Geolocation*>(user_data);
-    if(!timestamp || !ewkGeolocation)
-        return;
-
-    location_accuracy_level_e level;
-    double horizontal;
-    double vertical;
-
-    location_manager_get_last_accuracy(ewkGeolocation->locationManager, &level, &horizontal, &vertical);
-
-    WKRetainPtr<WKGeolocationPositionRef> position(AdoptWK, WKGeolocationPositionCreate(timestamp, latitude, longitude, horizontal));
-    WKGeolocationManagerProviderDidChangePosition(ewkGeolocation->geolocationManager.get(), position.get());
-}
-
-Ewk_Geolocation* ewkGeolocationCreateGeolocation(WKGeolocationManagerRef geolocationManager)
-{
-    Ewk_Geolocation* ewkGeolocation = new Ewk_Geolocation();
-    ewkGeolocation->geolocationManager = geolocationManager;
-    ewkGeolocation->started = false;
-
-    return ewkGeolocation;
-}
-
-void ewkGeolocationDeleteGeolocation(Ewk_Geolocation* ewkGeolocation)
-{
-    if (ewkGeolocation->started)
-        ewkGeolocationStopLocationManager(ewkGeolocation);
-
-    delete ewkGeolocation;
-}
-
 Ewk_Geolocation_Permission_Request* ewkGeolocationCreatePermissionRequest(Evas_Object* ewkView, WKGeolocationPermissionRequestRef geolocationPermissionRequestRef, WKSecurityOriginRef originRef)
 {
     return new Ewk_Geolocation_Permission_Request(ewkView, geolocationPermissionRequestRef, originRef);
@@ -119,66 +79,6 @@ bool ewkGeolocationIsPermissionRequestDecided(const Ewk_Geolocation_Permission_R
 {
     return permissionRequest->isDecided;
 }
-
-bool ewkGeolocationStartLocationManager(Ewk_Geolocation* ewkGeolocation)
-{
-    EINA_SAFETY_ON_NULL_RETURN_VAL(ewkGeolocation, false);
-
-    location_error_e ret = static_cast<location_error_e>(location_manager_create(LOCATIONS_METHOD_HYBRID, &ewkGeolocation->locationManager));
-    if (ret != LOCATIONS_ERROR_NONE) {
-        TIZEN_LOGE("location_manager_create error (%d)", ret);
-        return false;
-    }
-
-    ret = static_cast<location_error_e>(location_manager_set_position_updated_cb(ewkGeolocation->locationManager, ewkGeolocationPositionChangedCallback, 1, const_cast<Ewk_Geolocation*>(ewkGeolocation)));
-    if (ret != LOCATIONS_ERROR_NONE){
-        TIZEN_LOGE("location_manager_set_position_updated_cb error(%d)", ret);
-        location_manager_destroy(ewkGeolocation->locationManager);
-        return false;
-    }
-
-    ret = static_cast<location_error_e>(location_manager_start(ewkGeolocation->locationManager));
-    if (ret != LOCATIONS_ERROR_NONE) {
-        TIZEN_LOGE("location_manager_start error(%d)", ret);
-        location_manager_unset_position_updated_cb(ewkGeolocation->locationManager);
-        location_manager_destroy(ewkGeolocation->locationManager);
-        return false;
-    }
-
-    ewkGeolocation->started = true;
-
-    return true;
-}
-
-void ewkGeolocationStopLocationManager(Ewk_Geolocation* ewkGeolocation)
-{
-    EINA_SAFETY_ON_NULL_RETURN(ewkGeolocation);
-
-    if (!ewkGeolocation->started) {
-        TIZEN_LOGE("started error");
-        return;
-    }
-
-    location_error_e ret = static_cast<location_error_e>(location_manager_stop(ewkGeolocation->locationManager));
-    if (ret != LOCATIONS_ERROR_NONE) {
-        TIZEN_LOGE("location_manager_stop error(%d)", ret);
-        location_manager_destroy(ewkGeolocation->locationManager);
-    }
-
-    ret = static_cast<location_error_e>(location_manager_unset_position_updated_cb(ewkGeolocation->locationManager));
-    if (ret != LOCATIONS_ERROR_NONE) {
-        TIZEN_LOGE("location_manager_unset_position_updated_cb error(%d)", ret);
-        return;
-    }
-
-    ret = static_cast<location_error_e>(location_manager_destroy(ewkGeolocation->locationManager));
-    if (ret != LOCATIONS_ERROR_NONE) {
-        TIZEN_LOGE("location_manager_destroy error(%d)", ret);
-        return;
-    }
-
-    ewkGeolocation->started = false;
-}
 #endif
 
 const Ewk_Security_Origin* ewk_geolocation_permission_request_origin_get(const Ewk_Geolocation_Permission_Request* permissionRequest)
index 4e14e48..8fe92d0 100755 (executable)
 
 typedef struct _Ewk_Geolocation_Permission_Data Ewk_Geolocation_Permission_Data;
 
-Ewk_Geolocation* ewkGeolocationCreateGeolocation(WKGeolocationManagerRef);
 Ewk_Geolocation_Permission_Request* ewkGeolocationCreatePermissionRequest(Evas_Object* ewkView, WKGeolocationPermissionRequestRef, WKSecurityOriginRef);
-void ewkGeolocationDeleteGeolocation(Ewk_Geolocation*);
 void ewkGeolocationDeletePermissionRequestList(Eina_List* requestList);
 bool ewkGeolocationIsPermissionRequestSuspended(const Ewk_Geolocation_Permission_Request*);
 bool ewkGeolocationIsPermissionRequestDecided(const Ewk_Geolocation_Permission_Request*);
-bool ewkGeolocationStartLocationManager(Ewk_Geolocation*);
-void ewkGeolocationStopLocationManager(Ewk_Geolocation*);
 
 #endif // ENABLE(TIZEN_GEOLOCATION)
 
diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider.cpp
new file mode 100644 (file)
index 0000000..d00d162
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+   Copyright (C) 2012, 2013 Samsung Electronics
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "ewk_geolocation_provider.h"
+
+#if ENABLE(TIZEN_GEOLOCATION)
+#include "WKGeolocationManager.h"
+#include "ewk_geolocation_provider_private.h"
+#include "ewk_view_private.h"
+
+Ewk_Geolocation_Provider::Ewk_Geolocation_Provider(WKContextRef contextRef)
+    : m_wkContext(contextRef)
+{
+    ASSERT(m_wkContext.get());
+    WKGeolocationManagerRef geolocationManagerRef = WKContextGetGeolocationManager(m_wkContext.get());
+    ASSERT(geolocationManagerRef);
+
+    WKGeolocationProvider provider = {
+        kWKGeolocationProviderCurrentVersion,
+        this,
+        startUpdating,
+        stopUpdating,
+    };
+
+    WKGeolocationManagerSetProvider(geolocationManagerRef, &provider);
+}
+
+Ewk_Geolocation_Provider::~Ewk_Geolocation_Provider()
+{
+    stopUpdating(0, this);
+    WKGeolocationManagerSetProvider(wkGeolocationManager(), 0);
+}
+
+void Ewk_Geolocation_Provider::watchValidity(const GeolocationValidityCallbackData& callbackData)
+{
+    ASSERT(callbackData);
+    if (m_validityListeners.contains(callbackData.userData))
+        return;
+
+    m_validityListeners.add(callbackData.userData, callbackData);
+}
+
+void Ewk_Geolocation_Provider::unwatchValidity(void* userData)
+{
+    ASSERT(userData);
+    m_validityListeners.remove(userData);
+
+    if (m_locationManagerStarted && m_validityListeners.isEmpty()) {
+        TIZEN_LOGI("no validityListeners now. So stop updating... ");
+        stopUpdating(0, this);
+    }
+}
+
+WKGeolocationManagerRef Ewk_Geolocation_Provider::wkGeolocationManager()
+{
+    return WKContextGetGeolocationManager(m_wkContext.get());
+}
+
+static void ewkGeolocationProviderPositionChangedCallback(double latitude, double longitude, double altitude, time_t timestamp, void* user_data)
+{
+    Ewk_Geolocation_Provider* ewkGeolocationProvider = static_cast<Ewk_Geolocation_Provider*>(user_data);
+    if(!timestamp || !ewkGeolocationProvider)
+        return;
+
+    location_accuracy_level_e level;
+    double horizontal;
+    double vertical;
+
+    location_manager_get_last_accuracy(ewkGeolocationProvider->locationManager(), &level, &horizontal, &vertical);
+
+    WKRetainPtr<WKGeolocationPositionRef> position(AdoptWK, WKGeolocationPositionCreate(timestamp, latitude, longitude, horizontal));
+    WKGeolocationManagerProviderDidChangePosition(ewkGeolocationProvider->wkGeolocationManager(), position.get());
+}
+
+void Ewk_Geolocation_Provider::startUpdating(WKGeolocationManagerRef, const void* clientInfo)
+{
+    ASSERT(clientInfo);
+    Ewk_Geolocation_Provider* ewkGeolocationProvider = static_cast<Ewk_Geolocation_Provider*>(const_cast<void*>(clientInfo));
+
+    if (ewkGeolocationProvider->m_locationManagerStarted)
+        return;
+
+    if (ewkGeolocationProvider->m_validityListeners.isEmpty()) {
+        TIZEN_LOGE("No valid view exists");
+        WKGeolocationManagerProviderDidFailToDeterminePosition(ewkGeolocationProvider->wkGeolocationManager());
+        return;
+    }
+
+    ValidityListenerMap::const_iterator validtyListener = ewkGeolocationProvider->m_validityListeners.begin();
+    if (!validtyListener->second.callback(validtyListener->second.userData)) {
+        TIZEN_LOGE("No valid view exists");
+        WKGeolocationManagerProviderDidFailToDeterminePosition(ewkGeolocationProvider->wkGeolocationManager());
+        return;
+    }
+
+    location_error_e ret = static_cast<location_error_e>(location_manager_create(LOCATIONS_METHOD_HYBRID, &ewkGeolocationProvider->m_locationManager));
+    if (ret != LOCATIONS_ERROR_NONE) {
+        TIZEN_LOGE("location_manager_create error (%d)", ret);
+        WKGeolocationManagerProviderDidFailToDeterminePosition(ewkGeolocationProvider->wkGeolocationManager());
+        return;
+    }
+
+    ret = static_cast<location_error_e>(location_manager_set_position_updated_cb(ewkGeolocationProvider->m_locationManager, ewkGeolocationProviderPositionChangedCallback, 1, const_cast<Ewk_Geolocation_Provider*>(ewkGeolocationProvider)));
+    if (ret != LOCATIONS_ERROR_NONE){
+        TIZEN_LOGE("location_manager_set_position_updated_cb error(%d)", ret);
+        location_manager_destroy(ewkGeolocationProvider->m_locationManager);
+        WKGeolocationManagerProviderDidFailToDeterminePosition(ewkGeolocationProvider->wkGeolocationManager());
+        return;
+    }
+
+    ret = static_cast<location_error_e>(location_manager_start(ewkGeolocationProvider->m_locationManager));
+    if (ret != LOCATIONS_ERROR_NONE) {
+        TIZEN_LOGE("location_manager_start error(%d)", ret);
+        location_manager_unset_position_updated_cb(ewkGeolocationProvider->m_locationManager);
+        location_manager_destroy(ewkGeolocationProvider->m_locationManager);
+        WKGeolocationManagerProviderDidFailToDeterminePosition(ewkGeolocationProvider->wkGeolocationManager());
+        return;
+    }
+
+    ewkGeolocationProvider->m_locationManagerStarted = true;
+}
+
+void Ewk_Geolocation_Provider::stopUpdating(WKGeolocationManagerRef, const void* clientInfo)
+{
+    ASSERT(clientInfo);
+    Ewk_Geolocation_Provider* ewkGeolocationProvider = static_cast<Ewk_Geolocation_Provider*>(const_cast<void*>(clientInfo));
+
+    if (!ewkGeolocationProvider->m_locationManagerStarted) {
+        TIZEN_LOGE("started error");
+        return;
+    }
+
+    location_error_e ret = static_cast<location_error_e>(location_manager_stop(ewkGeolocationProvider->m_locationManager));
+    if (ret != LOCATIONS_ERROR_NONE) {
+        TIZEN_LOGE("location_manager_stop error(%d)", ret);
+        location_manager_destroy(ewkGeolocationProvider->m_locationManager);
+    }
+
+    ret = static_cast<location_error_e>(location_manager_unset_position_updated_cb(ewkGeolocationProvider->m_locationManager));
+    if (ret != LOCATIONS_ERROR_NONE) {
+        TIZEN_LOGE("location_manager_unset_position_updated_cb error(%d)", ret);
+        return;
+    }
+
+    ret = static_cast<location_error_e>(location_manager_destroy(ewkGeolocationProvider->m_locationManager));
+    if (ret != LOCATIONS_ERROR_NONE) {
+        TIZEN_LOGE("location_manager_destroy error(%d)", ret);
+        return;
+    }
+
+    ewkGeolocationProvider->m_locationManagerStarted = false;
+}
+#endif // ENABLE(TIZEN_GEOLOCATION)
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2012 Samsung Electronics
+   Copyright (C) 2012, 2013 Samsung Electronics
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
     Boston, MA 02110-1301, USA.
 */
 
-#ifndef ewk_view_geolocation_provider_h
-#define ewk_view_geolocation_provider_h
+/**
+ * @file ewk_geolocation_provider.h
+ * @brief Describes the Ewk Geolocation Provider API.
+ */
 
-#include "WKContext.h"
+#ifndef ewk_geolocation_provider_h
+#define ewk_geolocation_provider_h
 
-#include <Evas.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-void ewkViewGeolocationProviderAttachProvider(Evas_Object* ewkView, WKContextRef contextRef);
+/**
+ * @typedef Ewk_Geolocation_Provider Ewk_Geolocation_Provider
+ */
+typedef struct Ewk_Geolocation_Provider Ewk_Geolocation_Provider;
 
-#endif // ewk_view_geolocation_provider_h
+/**
+ * @typedef Ewk_Geolocation_Valididy_Cb Ewk_Geolocation_Valididy_Cb
+ */
+typedef Eina_Bool (*Ewk_Geolocation_Validity_Cb)(void* event_info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ewk_geolocation_provider_h
diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider_private.h b/Source/WebKit2/UIProcess/API/efl/ewk_geolocation_provider_private.h
new file mode 100644 (file)
index 0000000..997d6ff
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+   Copyright (C) 2013 Samsung Electronics
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ewk_geolocation_provider_private_h
+#define ewk_geolocation_provider_private_h
+
+#include "WKGeolocationManager.h"
+#include "WKRetainPtr.h"
+#include "ewk_geolocation_provider.h"
+#include <WebKit2/WKBase.h>
+#include <location/locations.h>
+#include <wtf/HashMap.h>
+
+struct GeolocationValidityCallbackData {
+    Ewk_Geolocation_Validity_Cb callback;
+    void* userData;
+
+    GeolocationValidityCallbackData()
+        : callback(0)
+        , userData(0)
+    { }
+
+    GeolocationValidityCallbackData(Ewk_Geolocation_Validity_Cb _callback, void* _userData)
+        : callback(_callback)
+        , userData(_userData)
+    { }
+};
+
+typedef HashMap<void*, GeolocationValidityCallbackData> ValidityListenerMap;
+
+class Ewk_Geolocation_Provider {
+public:
+    static PassOwnPtr<Ewk_Geolocation_Provider> create(WKContextRef contextRef)
+    {
+        return adoptPtr(new Ewk_Geolocation_Provider(contextRef));
+    }
+    ~Ewk_Geolocation_Provider();
+
+    void watchValidity(const GeolocationValidityCallbackData&);
+    void unwatchValidity(void*);
+    location_manager_h locationManager() { return m_locationManager; }
+    WKGeolocationManagerRef wkGeolocationManager();
+
+private:
+    explicit Ewk_Geolocation_Provider(WKContextRef contextRef);
+
+    static void startUpdating(WKGeolocationManagerRef, const void* clientInfo);
+    static void stopUpdating(WKGeolocationManagerRef, const void* clientInfo);
+
+    bool m_locationManagerStarted;
+    location_manager_h m_locationManager;
+    WKRetainPtr<WKContextRef> m_wkContext;
+    ValidityListenerMap m_validityListeners;
+};
+
+#endif // ewk_geolocation_provider_private_h
index 9d9f961..9cca291 100755 (executable)
@@ -108,8 +108,8 @@ namespace EGL {
 
 #if ENABLE(TIZEN_GEOLOCATION)
 #include "ewk_geolocation_private.h"
+#include "ewk_geolocation_provider_private.h"
 #include "ewk_security_origin.h"
-#include "ewk_view_geolocation_provider.h"
 #endif
 
 #if ENABLE(TOUCH_EVENTS)
@@ -280,6 +280,17 @@ static void _ewk_view_on_favicon_changed(const char* pageURL, void* eventInfo)
 }
 #endif
 
+#if ENABLE(TIZEN_GEOLOCATION)
+static Eina_Bool _ewk_view_geolocation_validity_check(void* eventInfo)
+{
+    Evas_Object* ewkView = static_cast<Evas_Object*>(eventInfo);
+    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, true);
+    EWK_VIEW_IMPL_GET_OR_RETURN(smartData, impl, true);
+
+    return impl->isValidLocationService();
+}
+#endif
+
 // Default Event Handling.
 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
 {
@@ -888,6 +899,16 @@ static void _ewk_view_smart_del(Evas_Object* ewkView)
     if (smartData && smartData->priv && smartData->priv->inputPicker->isColorPickerShown())
         ewk_view_color_picker_color_set(ewkView, 0, 0, 0, 0);
 #endif
+
+#if ENABLE(TIZEN_GEOLOCATION)
+    if (smartData) {
+        EWK_VIEW_IMPL_GET_OR_RETURN(smartData, impl);
+        Ewk_Geolocation_Provider* geolocationProvider = impl->context->geolocationProvider();
+        TIZEN_LOGI("_ewk_view_smart_del:: unwatch validity");
+        geolocationProvider->unwatchValidity(ewkView);
+    }
+#endif
+
     if (smartData && smartData->priv)
         _ewk_view_impl_del(smartData->priv);
 
@@ -1258,7 +1279,8 @@ static void _ewk_view_initialize(Evas_Object* ewkView, PassRefPtr<Ewk_Context> c
     ewkViewTizenClientAttachClient(ewkView);
 
 #if ENABLE(TIZEN_GEOLOCATION)
-    ewkViewGeolocationProviderAttachProvider(ewkView, impl->context->wkContext());
+    Ewk_Geolocation_Provider* geolocationProvider = impl->context->geolocationProvider();
+    geolocationProvider->watchValidity(GeolocationValidityCallbackData(_ewk_view_geolocation_validity_check, ewkView));
 #endif
 
 #if ENABLE(TIZEN_NOTIFICATIONS)
@@ -2364,31 +2386,6 @@ void ewkViewDeleteGeolocationPermission(Evas_Object* ewkView, Ewk_Geolocation_Pe
 
     impl->geolocationPermissionRequests = eina_list_remove(impl->geolocationPermissionRequests, geolocationPermissionRequest);
 }
-
-void ewkViewSetGeolocation(Evas_Object* ewkView, Ewk_Geolocation* geolocation)
-{
-    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
-    EWK_VIEW_IMPL_GET_OR_RETURN(smartData, impl);
-
-    impl->geolocation = geolocation;
-}
-
-Ewk_Geolocation* ewkViewGetGeolocation(Evas_Object* ewkView)
-{
-    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
-    EWK_VIEW_IMPL_GET_OR_RETURN(smartData, impl, 0);
-
-    return impl->geolocation;
-}
-
-bool ewkViewIsValidLocationService(Evas_Object* ewkView)
-{
-    TIZEN_LOGI("geolocation,valid");
-
-    bool valid = true;
-    evas_object_smart_callback_call(ewkView, "geolocation,valid", &valid);
-    return valid;
-}
 #endif
 
 void ewkViewFormSubmit(Evas_Object* ewkView, Ewk_Form_Data* formData)
diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view_geolocation_provider.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view_geolocation_provider.cpp
deleted file mode 100644 (file)
index d483e43..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-   Copyright (C) 2012 Samsung Electronics
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-#include "ewk_view_geolocation_provider.h"
-
-#if ENABLE(TIZEN_GEOLOCATION)
-#include "WKGeolocationManager.h"
-#include "ewk_view_private.h"
-
-static void startUpdating(WKGeolocationManagerRef geolocationManager, const void* clientInfo)
-{
-    Evas_Object* ewkView = static_cast<Evas_Object*>(const_cast<void*>(clientInfo));
-    Ewk_Geolocation* ewkGeolocation = ewkGeolocationCreateGeolocation(geolocationManager);
-
-    ewkViewSetGeolocation(ewkView, ewkGeolocation);
-    if (!ewkViewIsValidLocationService(ewkView) || !ewkGeolocationStartLocationManager(ewkGeolocation))
-        WKGeolocationManagerProviderDidFailToDeterminePosition(geolocationManager);
-}
-
-static void stopUpdating(WKGeolocationManagerRef geolocationManager, const void* clientInfo)
-{
-    Evas_Object* ewkView = static_cast<Evas_Object*>(const_cast<void*>(clientInfo));
-    ewkGeolocationStopLocationManager(ewkViewGetGeolocation(ewkView));
-}
-
-void ewkViewGeolocationProviderAttachProvider(Evas_Object* ewkView, WKContextRef contextRef)
-{
-    EINA_SAFETY_ON_NULL_RETURN(ewkView);
-
-    WKGeolocationProvider provider = {
-        kWKGeolocationProviderCurrentVersion,
-        ewkView, // clientInfo
-        startUpdating,
-        stopUpdating
-    };
-
-    WKGeolocationManagerRef geolocationManager = WKContextGetGeolocationManager(contextRef);
-    WKGeolocationManagerSetProvider(geolocationManager, &provider);
-}
-#endif // ENABLE(TIZEN_GEOLOCATION)
index 4e5897e..3c6901e 100755 (executable)
@@ -86,10 +86,6 @@ class PageClientImpl;
 
 typedef struct Ewk_Context Ewk_Context;
 
-#if ENABLE(TIZEN_GEOLOCATION)
-typedef struct _Ewk_Geolocation Ewk_Geolocation;
-#endif
-
 bool ewk_view_focused_node_adjust(Evas_Object* object, Eina_Bool adjustForExternalKeyboard = EINA_FALSE, Eina_Bool adjustForContentSizeChanged = EINA_FALSE);
 void ewk_view_touch_event_handler_result_set(Evas_Object* ewkView, WebKit::WebEvent::Type type, bool wasHandled);
 
@@ -178,11 +174,8 @@ unsigned long long ewkContextGetNewQuotaForExceededQuota(Ewk_Context* context, E
 #endif
 
 #if ENABLE(TIZEN_GEOLOCATION)
-void ewkViewSetGeolocation(Evas_Object* ewkView, Ewk_Geolocation*);
-Ewk_Geolocation* ewkViewGetGeolocation(Evas_Object* ewkView);
 void ewkViewRequestGeolocationPermission(Evas_Object* ewkView, Ewk_Geolocation_Permission_Request*);
 void ewkViewDeleteGeolocationPermission(Evas_Object* ewkView, Ewk_Geolocation_Permission_Request*);
-bool ewkViewIsValidLocationService(Evas_Object* ewkView);
 #endif
 
 #if ENABLE(TIZEN_NOTIFICATIONS)