Chromium Code Reviews| 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 |