Index: content/browser/geofencing/geofencing_manager.cc |
diff --git a/content/browser/geofencing/geofencing_manager.cc b/content/browser/geofencing/geofencing_manager.cc |
index 94b0f25dcedf5a7d8ad5ab6c9ca3c1e898b56726..98477184ca103462a6ec0d0a4206d0bf139f38bb 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_CURRENTLY_ON(BrowserThread::UI); |
+ StoragePartition* partition = BrowserContext::GetStoragePartitionForSite( |
michaeln
2014/10/14 02:20:40
I don't see how this can be correct?
An app embed
Marijn Kruisselbrink
2014/10/14 19:16:55
Ah yes, you're right of course. That also means th
Marijn Kruisselbrink
2014/10/15 23:55:15
Okay, I did this refactoring of GeofencingManager
|
+ 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_CURRENTLY_ON(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_CURRENTLY_ON(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_CURRENTLY_ON(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( |
michaeln
2014/10/14 02:20:40
need to be more defensive about active_version() b
Marijn Kruisselbrink
2014/10/14 19:16:55
Hmm, okay... So what I think should happen if a ge
falken
2014/10/15 01:59:34
I haven't been closely following...
There's a few
Marijn Kruisselbrink
2014/10/15 23:55:15
I'm not sure, I think generally events are only de
falken
2014/10/16 05:18:18
TODO sounds good. We sometimes dispatch events to
|
+ 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_CURRENTLY_ON(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 |