Index: content/browser/geofencing/geofencing_manager.cc |
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc |
index 4967dbe5ee3f0d394a2f6f90dbf019f33f08c87b..8f7b1944059116b96faaa44e0eed20999c8c0c8d 100644 |
--- a/content/browser/geofencing/geofencing_manager.cc |
+++ b/content/browser/geofencing/geofencing_manager.cc |
@@ -9,12 +9,68 @@ |
#include "base/callback.h" |
#include "base/memory/singleton.h" |
#include "content/browser/geofencing/geofencing_provider.h" |
+#include "content/browser/service_worker/service_worker_context_wrapper.h" |
+#include "content/public/browser/browser_context.h" |
#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/storage_partition.h" |
#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" |
+#include "third_party/WebKit/public/platform/WebGeofencingEventType.h" |
#include "url/gurl.h" |
namespace content { |
+namespace { |
+ |
+scoped_refptr<ServiceWorkerContextWrapper> FindServiceWorkerContextOnUIThread( |
+ BrowserContext* browser_context, |
+ const GURL& service_worker_origin) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
Michael van Ouwerkerk
2014/10/08 16:42:00
Nit: use DCHECK_CURRENTLY_ON here and below.
Marijn Kruisselbrink
2014/10/09 22:56:56
Done.
|
+ StoragePartition* partition = BrowserContext::GetStoragePartitionForSite( |
+ browser_context, service_worker_origin); |
+ return static_cast<ServiceWorkerContextWrapper*>( |
+ partition->GetServiceWorkerContext()); |
+} |
+ |
+void FindServiceWorkerRegistration( |
+ int64 service_worker_registration_id, |
+ const GURL& service_worker_origin, |
+ const ServiceWorkerStorage::FindRegistrationCallback& callback, |
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ service_worker_context->context()->storage()->FindRegistrationForId( |
+ service_worker_registration_id, service_worker_origin, callback); |
+} |
+ |
+void DeliverGeofencingEventEnd( |
+ const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, |
+ ServiceWorkerStatusCode service_worker_status) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ // TODO(mek): log/check result. |
+} |
+ |
+void DeliverGeofencingEvent(blink::WebGeofencingEventType event_type, |
+ const std::string& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ ServiceWorkerStatusCode service_worker_status, |
+ const scoped_refptr<ServiceWorkerRegistration>& |
+ service_worker_registration) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (service_worker_status == SERVICE_WORKER_OK) { |
+ // Hold on to the service worker registration in the callback to keep it |
+ // alive until the callback dies. Otherwise the registration could be |
+ // released when this method returns - before the event is delivered to the |
+ // service worker. |
+ base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback = |
+ base::Bind(&DeliverGeofencingEventEnd, service_worker_registration); |
+ service_worker_registration->active_version()->DispatchGeofencingEvent( |
+ dispatch_event_callback, event_type, region_id, region); |
+ } else { |
+ // TODO(mek): no SW, cleanup/logging |
+ } |
+} |
+ |
+} // namespace |
+ |
struct GeofencingManager::RegistrationKey { |
RegistrationKey(BrowserContext* browser_context, |
int64 service_worker_registration_id, |
@@ -200,6 +256,14 @@ GeofencingStatus GeofencingManager::GetRegisteredRegions( |
return GeofencingStatus::GEOFENCING_STATUS_OK; |
} |
+void GeofencingManager::RegionEntered(int provider_id) { |
+ DispatchGeofencingEvent(blink::WebGeofencingEventTypeEnter, provider_id); |
+} |
+ |
+void GeofencingManager::RegionExited(int provider_id) { |
+ DispatchGeofencingEvent(blink::WebGeofencingEventTypeLeave, provider_id); |
+} |
+ |
void GeofencingManager::RegisterRegionCompleted(const StatusCallback& callback, |
const RegistrationKey& key, |
GeofencingStatus status, |
@@ -249,4 +313,36 @@ void GeofencingManager::ClearRegistration(const RegistrationKey& key) { |
registrations_.erase(it); |
} |
+GeofencingManager::Registration* |
+GeofencingManager::FindRegistrationByProviderId(int provider_id) { |
+ for (Registration& registration : registrations_) { |
+ if (registration.registration_id == provider_id) |
+ return ®istration; |
+ } |
+ return nullptr; |
+} |
+ |
+void GeofencingManager::DispatchGeofencingEvent( |
+ blink::WebGeofencingEventType event_type, |
+ int provider_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ Registration* registration = FindRegistrationByProviderId(provider_id); |
+ if (!registration || registration->key.service_worker_registration_id < 0) |
+ return; |
+ |
+ BrowserThread::PostTaskAndReplyWithResult( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&FindServiceWorkerContextOnUIThread, |
+ registration->key.browser_context, |
+ registration->key.service_worker_origin), |
+ base::Bind(&FindServiceWorkerRegistration, |
+ registration->key.service_worker_registration_id, |
+ registration->key.service_worker_origin, |
+ base::Bind(&DeliverGeofencingEvent, |
+ event_type, |
+ registration->key.region_id, |
+ registration->region))); |
+} |
+ |
} // namespace content |