Index: content/child/geofencing/geofencing_dispatcher.cc |
diff --git a/content/child/geofencing/geofencing_dispatcher.cc b/content/child/geofencing/geofencing_dispatcher.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bde74283d3cd9bcda4b17df2042f11b39cd2ed8a |
--- /dev/null |
+++ b/content/child/geofencing/geofencing_dispatcher.cc |
@@ -0,0 +1,183 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/child/geofencing/geofencing_dispatcher.h" |
+ |
+#include "base/lazy_instance.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "content/child/thread_safe_sender.h" |
+#include "content/child/worker_thread_task_runner.h" |
+#include "content/common/geofencing_messages.h" |
+#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" |
+#include "third_party/WebKit/public/platform/WebGeofencingError.h" |
+#include "third_party/WebKit/public/platform/WebGeofencingRegistration.h" |
+ |
+using blink::WebGeofencingError; |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+base::LazyInstance<base::ThreadLocalPointer<GeofencingDispatcher> >::Leaky |
+ g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; |
+ |
+GeofencingDispatcher* const kHasBeenDeleted = |
+ reinterpret_cast<GeofencingDispatcher*>(0x1); |
+ |
+int CurrentWorkerId() { |
+ return WorkerTaskRunner::Instance()->CurrentWorkerId(); |
+} |
+ |
+} // namespace |
+ |
+GeofencingDispatcher::GeofencingDispatcher(ThreadSafeSender* sender) |
+ : thread_safe_sender_(sender) { |
+ g_dispatcher_tls.Pointer()->Set(this); |
+} |
+ |
+GeofencingDispatcher::~GeofencingDispatcher() { |
+ g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); |
+} |
+ |
+bool GeofencingDispatcher::Send(IPC::Message* msg) { |
+ return thread_safe_sender_->Send(msg); |
+} |
+ |
+void GeofencingDispatcher::OnMessageReceived(const IPC::Message& msg) { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(GeofencingDispatcher, msg) |
+ IPC_MESSAGE_HANDLER(GeofencingMsg_RegisterRegionComplete, |
+ OnRegisterRegionComplete) |
+ IPC_MESSAGE_HANDLER(GeofencingMsg_UnregisterRegionComplete, |
+ OnUnregisterRegionComplete) |
+ IPC_MESSAGE_HANDLER(GeofencingMsg_GetRegisteredRegionsComplete, |
+ OnGetRegisteredRegionsComplete) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ DCHECK(handled) << "Unhandled message:" << msg.type(); |
+} |
+ |
+void GeofencingDispatcher::RegisterRegion( |
+ const blink::WebString& region_id, |
+ const blink::WebCircularGeofencingRegion& region, |
+ blink::WebGeofencingCallbacks* raw_callbacks) { |
Michael van Ouwerkerk
2014/09/15 13:06:49
Why are these variables sometimes called "raw_call
Marijn Kruisselbrink
2014/09/17 00:04:24
At some point I named them raw_callbacks because I
|
+ DCHECK(raw_callbacks); |
+ int request_id = region_registration_requests_.Add(raw_callbacks); |
+ Send(new GeofencingHostMsg_RegisterRegion( |
+ CurrentWorkerId(), request_id, region_id.utf8(), region)); |
+} |
+ |
+void GeofencingDispatcher::UnregisterRegion( |
+ const blink::WebString& region_id, |
+ blink::WebGeofencingCallbacks* raw_callbacks) { |
+ DCHECK(raw_callbacks); |
+ int request_id = region_unregistration_requests_.Add(raw_callbacks); |
+ Send(new GeofencingHostMsg_UnregisterRegion( |
+ CurrentWorkerId(), request_id, region_id.utf8())); |
+} |
+ |
+void GeofencingDispatcher::GetRegisteredRegions( |
+ blink::WebGeofencingRegionsCallbacks* raw_callbacks) { |
+ DCHECK(raw_callbacks); |
+ int request_id = get_registered_regions_requests_.Add(raw_callbacks); |
+ Send(new GeofencingHostMsg_GetRegisteredRegions(CurrentWorkerId(), |
+ request_id)); |
+} |
+ |
+GeofencingDispatcher* GeofencingDispatcher::GetOrCreateThreadSpecificInstance( |
+ ThreadSafeSender* thread_safe_sender) { |
+ if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { |
+ NOTREACHED() << "Re-instantiating TLS GeofencingDispatcher."; |
Michael van Ouwerkerk
2014/09/15 13:06:50
Why can't this be a CHECK?
Marijn Kruisselbrink
2014/09/17 00:04:24
NOTREACHED would be the equivalent of a DCHECK, no
|
+ g_dispatcher_tls.Pointer()->Set(NULL); |
+ } |
+ if (g_dispatcher_tls.Pointer()->Get()) |
+ return g_dispatcher_tls.Pointer()->Get(); |
+ |
+ GeofencingDispatcher* dispatcher = |
+ new GeofencingDispatcher(thread_safe_sender); |
+ if (WorkerTaskRunner::Instance()->CurrentWorkerId()) |
+ WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); |
+ return dispatcher; |
+} |
+ |
+GeofencingDispatcher* GeofencingDispatcher::GetThreadSpecificInstance() { |
+ if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) |
+ return NULL; |
+ return g_dispatcher_tls.Pointer()->Get(); |
+} |
+ |
+void GeofencingDispatcher::OnRegisterRegionComplete(int thread_id, |
+ int request_id, |
+ GeofencingStatus status) { |
+ blink::WebGeofencingCallbacks* callbacks = |
+ region_registration_requests_.Lookup(request_id); |
+ DCHECK(callbacks); |
+ if (!callbacks) |
+ return; |
+ |
+ if (status == GEOFENCING_STATUS_OK) { |
+ callbacks->onSuccess(); |
+ } else { |
+ callbacks->onError(new WebGeofencingError( |
+ WebGeofencingError::ErrorTypeAbort, |
+ blink::WebString::fromUTF8(GeofencingStatusToString(status)))); |
+ } |
+ region_registration_requests_.Remove(request_id); |
+} |
+ |
+void GeofencingDispatcher::OnUnregisterRegionComplete(int thread_id, |
+ int request_id, |
+ GeofencingStatus status) { |
+ blink::WebGeofencingCallbacks* callbacks = |
+ region_unregistration_requests_.Lookup(request_id); |
+ DCHECK(callbacks); |
+ if (!callbacks) |
+ return; |
+ |
+ if (status == GEOFENCING_STATUS_OK) { |
+ callbacks->onSuccess(); |
+ } else { |
+ callbacks->onError(new WebGeofencingError( |
+ WebGeofencingError::ErrorTypeAbort, |
+ blink::WebString::fromUTF8(GeofencingStatusToString(status)))); |
+ } |
+ region_unregistration_requests_.Remove(request_id); |
+} |
+ |
+void GeofencingDispatcher::OnGetRegisteredRegionsComplete( |
+ int thread_id, |
+ int request_id, |
+ GeofencingStatus status, |
+ const GeofencingRegistrations& regions) { |
+ blink::WebGeofencingRegionsCallbacks* callbacks = |
+ get_registered_regions_requests_.Lookup(request_id); |
+ DCHECK(callbacks); |
+ if (!callbacks) |
+ return; |
+ |
+ if (status == GEOFENCING_STATUS_OK) { |
+ scoped_ptr<blink::WebVector<blink::WebGeofencingRegistration> > result( |
+ new blink::WebVector<blink::WebGeofencingRegistration>(regions.size())); |
+ size_t index = 0; |
+ for (GeofencingRegistrations::const_iterator it = regions.begin(); |
+ it != regions.end(); ++it, ++index) { |
+ (*result)[index].id = blink::WebString::fromUTF8(it->first); |
+ (*result)[index].region = it->second; |
+ } |
+ callbacks->onSuccess(result.release()); |
+ } else { |
+ callbacks->onError(new WebGeofencingError( |
+ WebGeofencingError::ErrorTypeAbort, |
+ blink::WebString::fromUTF8(GeofencingStatusToString(status)))); |
+ } |
+ get_registered_regions_requests_.Remove(request_id); |
+} |
+ |
+void GeofencingDispatcher::OnWorkerRunLoopStopped() { |
+ delete this; |
+} |
+ |
+} // namespace content |