OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/child/geofencing/geofencing_dispatcher.h" | |
6 | |
7 #include "base/lazy_instance.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/thread_task_runner_handle.h" | |
11 #include "content/child/thread_safe_sender.h" | |
12 #include "content/child/worker_thread_task_runner.h" | |
13 #include "content/common/geofencing_messages.h" | |
14 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" | |
15 #include "third_party/WebKit/public/platform/WebGeofencingError.h" | |
16 #include "third_party/WebKit/public/platform/WebGeofencingRegistration.h" | |
17 | |
18 using blink::WebGeofencingError; | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 | |
24 base::LazyInstance<base::ThreadLocalPointer<GeofencingDispatcher> >::Leaky | |
25 g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; | |
26 | |
27 GeofencingDispatcher* const kHasBeenDeleted = | |
28 reinterpret_cast<GeofencingDispatcher*>(0x1); | |
29 | |
30 int CurrentWorkerId() { | |
31 return WorkerTaskRunner::Instance()->CurrentWorkerId(); | |
32 } | |
33 | |
34 } // namespace | |
35 | |
36 GeofencingDispatcher::GeofencingDispatcher(ThreadSafeSender* sender) | |
37 : thread_safe_sender_(sender) { | |
38 g_dispatcher_tls.Pointer()->Set(this); | |
39 } | |
40 | |
41 GeofencingDispatcher::~GeofencingDispatcher() { | |
42 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | |
43 } | |
44 | |
45 bool GeofencingDispatcher::Send(IPC::Message* msg) { | |
46 return thread_safe_sender_->Send(msg); | |
47 } | |
48 | |
49 void GeofencingDispatcher::OnMessageReceived(const IPC::Message& msg) { | |
50 bool handled = true; | |
51 IPC_BEGIN_MESSAGE_MAP(GeofencingDispatcher, msg) | |
52 IPC_MESSAGE_HANDLER(GeofencingMsg_RegisterRegionComplete, | |
53 OnRegisterRegionComplete) | |
54 IPC_MESSAGE_HANDLER(GeofencingMsg_UnregisterRegionComplete, | |
55 OnUnregisterRegionComplete) | |
56 IPC_MESSAGE_HANDLER(GeofencingMsg_GetRegisteredRegionsComplete, | |
57 OnGetRegisteredRegionsComplete) | |
58 IPC_MESSAGE_UNHANDLED(handled = false) | |
59 IPC_END_MESSAGE_MAP() | |
60 DCHECK(handled) << "Unhandled message:" << msg.type(); | |
61 } | |
62 | |
63 void GeofencingDispatcher::RegisterRegion( | |
64 const blink::WebString& region_id, | |
65 const blink::WebCircularGeofencingRegion& region, | |
66 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
| |
67 DCHECK(raw_callbacks); | |
68 int request_id = region_registration_requests_.Add(raw_callbacks); | |
69 Send(new GeofencingHostMsg_RegisterRegion( | |
70 CurrentWorkerId(), request_id, region_id.utf8(), region)); | |
71 } | |
72 | |
73 void GeofencingDispatcher::UnregisterRegion( | |
74 const blink::WebString& region_id, | |
75 blink::WebGeofencingCallbacks* raw_callbacks) { | |
76 DCHECK(raw_callbacks); | |
77 int request_id = region_unregistration_requests_.Add(raw_callbacks); | |
78 Send(new GeofencingHostMsg_UnregisterRegion( | |
79 CurrentWorkerId(), request_id, region_id.utf8())); | |
80 } | |
81 | |
82 void GeofencingDispatcher::GetRegisteredRegions( | |
83 blink::WebGeofencingRegionsCallbacks* raw_callbacks) { | |
84 DCHECK(raw_callbacks); | |
85 int request_id = get_registered_regions_requests_.Add(raw_callbacks); | |
86 Send(new GeofencingHostMsg_GetRegisteredRegions(CurrentWorkerId(), | |
87 request_id)); | |
88 } | |
89 | |
90 GeofencingDispatcher* GeofencingDispatcher::GetOrCreateThreadSpecificInstance( | |
91 ThreadSafeSender* thread_safe_sender) { | |
92 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | |
93 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
| |
94 g_dispatcher_tls.Pointer()->Set(NULL); | |
95 } | |
96 if (g_dispatcher_tls.Pointer()->Get()) | |
97 return g_dispatcher_tls.Pointer()->Get(); | |
98 | |
99 GeofencingDispatcher* dispatcher = | |
100 new GeofencingDispatcher(thread_safe_sender); | |
101 if (WorkerTaskRunner::Instance()->CurrentWorkerId()) | |
102 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); | |
103 return dispatcher; | |
104 } | |
105 | |
106 GeofencingDispatcher* GeofencingDispatcher::GetThreadSpecificInstance() { | |
107 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) | |
108 return NULL; | |
109 return g_dispatcher_tls.Pointer()->Get(); | |
110 } | |
111 | |
112 void GeofencingDispatcher::OnRegisterRegionComplete(int thread_id, | |
113 int request_id, | |
114 GeofencingStatus status) { | |
115 blink::WebGeofencingCallbacks* callbacks = | |
116 region_registration_requests_.Lookup(request_id); | |
117 DCHECK(callbacks); | |
118 if (!callbacks) | |
119 return; | |
120 | |
121 if (status == GEOFENCING_STATUS_OK) { | |
122 callbacks->onSuccess(); | |
123 } else { | |
124 callbacks->onError(new WebGeofencingError( | |
125 WebGeofencingError::ErrorTypeAbort, | |
126 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
127 } | |
128 region_registration_requests_.Remove(request_id); | |
129 } | |
130 | |
131 void GeofencingDispatcher::OnUnregisterRegionComplete(int thread_id, | |
132 int request_id, | |
133 GeofencingStatus status) { | |
134 blink::WebGeofencingCallbacks* callbacks = | |
135 region_unregistration_requests_.Lookup(request_id); | |
136 DCHECK(callbacks); | |
137 if (!callbacks) | |
138 return; | |
139 | |
140 if (status == GEOFENCING_STATUS_OK) { | |
141 callbacks->onSuccess(); | |
142 } else { | |
143 callbacks->onError(new WebGeofencingError( | |
144 WebGeofencingError::ErrorTypeAbort, | |
145 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
146 } | |
147 region_unregistration_requests_.Remove(request_id); | |
148 } | |
149 | |
150 void GeofencingDispatcher::OnGetRegisteredRegionsComplete( | |
151 int thread_id, | |
152 int request_id, | |
153 GeofencingStatus status, | |
154 const GeofencingRegistrations& regions) { | |
155 blink::WebGeofencingRegionsCallbacks* callbacks = | |
156 get_registered_regions_requests_.Lookup(request_id); | |
157 DCHECK(callbacks); | |
158 if (!callbacks) | |
159 return; | |
160 | |
161 if (status == GEOFENCING_STATUS_OK) { | |
162 scoped_ptr<blink::WebVector<blink::WebGeofencingRegistration> > result( | |
163 new blink::WebVector<blink::WebGeofencingRegistration>(regions.size())); | |
164 size_t index = 0; | |
165 for (GeofencingRegistrations::const_iterator it = regions.begin(); | |
166 it != regions.end(); ++it, ++index) { | |
167 (*result)[index].id = blink::WebString::fromUTF8(it->first); | |
168 (*result)[index].region = it->second; | |
169 } | |
170 callbacks->onSuccess(result.release()); | |
171 } else { | |
172 callbacks->onError(new WebGeofencingError( | |
173 WebGeofencingError::ErrorTypeAbort, | |
174 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
175 } | |
176 get_registered_regions_requests_.Remove(request_id); | |
177 } | |
178 | |
179 void GeofencingDispatcher::OnWorkerRunLoopStopped() { | |
180 delete this; | |
181 } | |
182 | |
183 } // namespace content | |
OLD | NEW |