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 <stddef.h> | |
8 #include <stdint.h> | |
9 | |
10 #include <memory> | |
11 | |
12 #include "base/lazy_instance.h" | |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/threading/thread_task_runner_handle.h" | |
15 #include "content/child/service_worker/web_service_worker_registration_impl.h" | |
16 #include "content/child/thread_safe_sender.h" | |
17 #include "content/common/geofencing_messages.h" | |
18 #include "content/common/service_worker/service_worker_types.h" | |
19 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" | |
20 #include "third_party/WebKit/public/platform/WebGeofencingError.h" | |
21 #include "third_party/WebKit/public/platform/WebGeofencingRegistration.h" | |
22 | |
23 using blink::WebGeofencingError; | |
24 | |
25 namespace content { | |
26 | |
27 namespace { | |
28 | |
29 base::LazyInstance<base::ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = | |
30 LAZY_INSTANCE_INITIALIZER; | |
31 | |
32 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); | |
33 | |
34 int CurrentWorkerId() { | |
35 return WorkerThread::GetCurrentId(); | |
36 } | |
37 | |
38 } // namespace | |
39 | |
40 GeofencingDispatcher::GeofencingDispatcher(ThreadSafeSender* sender) | |
41 : thread_safe_sender_(sender) { | |
42 g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this)); | |
43 } | |
44 | |
45 GeofencingDispatcher::~GeofencingDispatcher() { | |
46 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | |
47 } | |
48 | |
49 bool GeofencingDispatcher::Send(IPC::Message* msg) { | |
50 return thread_safe_sender_->Send(msg); | |
51 } | |
52 | |
53 void GeofencingDispatcher::OnMessageReceived(const IPC::Message& msg) { | |
54 bool handled = true; | |
55 IPC_BEGIN_MESSAGE_MAP(GeofencingDispatcher, msg) | |
56 IPC_MESSAGE_HANDLER(GeofencingMsg_RegisterRegionComplete, | |
57 OnRegisterRegionComplete) | |
58 IPC_MESSAGE_HANDLER(GeofencingMsg_UnregisterRegionComplete, | |
59 OnUnregisterRegionComplete) | |
60 IPC_MESSAGE_HANDLER(GeofencingMsg_GetRegisteredRegionsComplete, | |
61 OnGetRegisteredRegionsComplete) | |
62 IPC_MESSAGE_UNHANDLED(handled = false) | |
63 IPC_END_MESSAGE_MAP() | |
64 DCHECK(handled) << "Unhandled message:" << msg.type(); | |
65 } | |
66 | |
67 void GeofencingDispatcher::RegisterRegion( | |
68 const blink::WebString& region_id, | |
69 const blink::WebCircularGeofencingRegion& region, | |
70 blink::WebServiceWorkerRegistration* service_worker_registration, | |
71 blink::WebGeofencingCallbacks* callbacks) { | |
72 DCHECK(callbacks); | |
73 int request_id = region_registration_requests_.Add(callbacks); | |
74 // TODO(mek): Immediately reject requests lacking a service worker | |
75 // registration, without bouncing through browser process. | |
76 int64_t serviceworker_registration_id = kInvalidServiceWorkerRegistrationId; | |
77 if (service_worker_registration) { | |
78 serviceworker_registration_id = | |
79 static_cast<WebServiceWorkerRegistrationImpl*>( | |
80 service_worker_registration)->registration_id(); | |
81 } | |
82 Send(new GeofencingHostMsg_RegisterRegion(CurrentWorkerId(), | |
83 request_id, | |
84 region_id.utf8(), | |
85 region, | |
86 serviceworker_registration_id)); | |
87 } | |
88 | |
89 void GeofencingDispatcher::UnregisterRegion( | |
90 const blink::WebString& region_id, | |
91 blink::WebServiceWorkerRegistration* service_worker_registration, | |
92 blink::WebGeofencingCallbacks* callbacks) { | |
93 DCHECK(callbacks); | |
94 int request_id = region_unregistration_requests_.Add(callbacks); | |
95 // TODO(mek): Immediately reject requests lacking a service worker | |
96 // registration, without bouncing through browser process. | |
97 int64_t serviceworker_registration_id = kInvalidServiceWorkerRegistrationId; | |
98 if (service_worker_registration) { | |
99 serviceworker_registration_id = | |
100 static_cast<WebServiceWorkerRegistrationImpl*>( | |
101 service_worker_registration)->registration_id(); | |
102 } | |
103 Send(new GeofencingHostMsg_UnregisterRegion(CurrentWorkerId(), | |
104 request_id, | |
105 region_id.utf8(), | |
106 serviceworker_registration_id)); | |
107 } | |
108 | |
109 void GeofencingDispatcher::GetRegisteredRegions( | |
110 blink::WebServiceWorkerRegistration* service_worker_registration, | |
111 blink::WebGeofencingRegionsCallbacks* callbacks) { | |
112 DCHECK(callbacks); | |
113 int request_id = get_registered_regions_requests_.Add(callbacks); | |
114 // TODO(mek): Immediately reject requests lacking a service worker | |
115 // registration, without bouncing through browser process. | |
116 int64_t serviceworker_registration_id = kInvalidServiceWorkerRegistrationId; | |
117 if (service_worker_registration) { | |
118 serviceworker_registration_id = | |
119 static_cast<WebServiceWorkerRegistrationImpl*>( | |
120 service_worker_registration)->registration_id(); | |
121 } | |
122 Send(new GeofencingHostMsg_GetRegisteredRegions( | |
123 CurrentWorkerId(), request_id, serviceworker_registration_id)); | |
124 } | |
125 | |
126 void GeofencingDispatcher::SetMockProvider(bool service_available) { | |
127 Send(new GeofencingHostMsg_SetMockProvider( | |
128 service_available ? GeofencingMockState::SERVICE_AVAILABLE | |
129 : GeofencingMockState::SERVICE_UNAVAILABLE)); | |
130 } | |
131 | |
132 void GeofencingDispatcher::ClearMockProvider() { | |
133 Send(new GeofencingHostMsg_SetMockProvider(GeofencingMockState::NONE)); | |
134 } | |
135 | |
136 void GeofencingDispatcher::SetMockPosition(double latitude, double longitude) { | |
137 Send(new GeofencingHostMsg_SetMockPosition(latitude, longitude)); | |
138 } | |
139 | |
140 GeofencingDispatcher* GeofencingDispatcher::GetOrCreateThreadSpecificInstance( | |
141 ThreadSafeSender* thread_safe_sender) { | |
142 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | |
143 NOTREACHED() << "Re-instantiating TLS GeofencingDispatcher."; | |
144 g_dispatcher_tls.Pointer()->Set(NULL); | |
145 } | |
146 if (g_dispatcher_tls.Pointer()->Get()) | |
147 return static_cast<GeofencingDispatcher*>( | |
148 g_dispatcher_tls.Pointer()->Get()); | |
149 | |
150 GeofencingDispatcher* dispatcher = | |
151 new GeofencingDispatcher(thread_safe_sender); | |
152 if (WorkerThread::GetCurrentId()) | |
153 WorkerThread::AddObserver(dispatcher); | |
154 return dispatcher; | |
155 } | |
156 | |
157 GeofencingDispatcher* GeofencingDispatcher::GetThreadSpecificInstance() { | |
158 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) | |
159 return NULL; | |
160 return static_cast<GeofencingDispatcher*>(g_dispatcher_tls.Pointer()->Get()); | |
161 } | |
162 | |
163 void GeofencingDispatcher::OnRegisterRegionComplete(int thread_id, | |
164 int request_id, | |
165 GeofencingStatus status) { | |
166 blink::WebGeofencingCallbacks* callbacks = | |
167 region_registration_requests_.Lookup(request_id); | |
168 DCHECK(callbacks); | |
169 | |
170 if (status == GEOFENCING_STATUS_OK) { | |
171 callbacks->onSuccess(); | |
172 } else { | |
173 callbacks->onError(WebGeofencingError( | |
174 WebGeofencingError::ErrorTypeAbort, | |
175 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
176 } | |
177 region_registration_requests_.Remove(request_id); | |
178 } | |
179 | |
180 void GeofencingDispatcher::OnUnregisterRegionComplete(int thread_id, | |
181 int request_id, | |
182 GeofencingStatus status) { | |
183 blink::WebGeofencingCallbacks* callbacks = | |
184 region_unregistration_requests_.Lookup(request_id); | |
185 DCHECK(callbacks); | |
186 | |
187 if (status == GEOFENCING_STATUS_OK) { | |
188 callbacks->onSuccess(); | |
189 } else { | |
190 callbacks->onError(WebGeofencingError( | |
191 WebGeofencingError::ErrorTypeAbort, | |
192 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
193 } | |
194 region_unregistration_requests_.Remove(request_id); | |
195 } | |
196 | |
197 void GeofencingDispatcher::OnGetRegisteredRegionsComplete( | |
198 int thread_id, | |
199 int request_id, | |
200 GeofencingStatus status, | |
201 const GeofencingRegistrations& regions) { | |
202 blink::WebGeofencingRegionsCallbacks* callbacks = | |
203 get_registered_regions_requests_.Lookup(request_id); | |
204 DCHECK(callbacks); | |
205 | |
206 if (status == GEOFENCING_STATUS_OK) { | |
207 blink::WebVector<blink::WebGeofencingRegistration> result(regions.size()); | |
208 size_t index = 0; | |
209 for (GeofencingRegistrations::const_iterator it = regions.begin(); | |
210 it != regions.end(); | |
211 ++it, ++index) { | |
212 result[index].id = blink::WebString::fromUTF8(it->first); | |
213 result[index].region = it->second; | |
214 } | |
215 callbacks->onSuccess(result); | |
216 } else { | |
217 callbacks->onError(WebGeofencingError( | |
218 WebGeofencingError::ErrorTypeAbort, | |
219 blink::WebString::fromUTF8(GeofencingStatusToString(status)))); | |
220 } | |
221 get_registered_regions_requests_.Remove(request_id); | |
222 } | |
223 | |
224 void GeofencingDispatcher::WillStopCurrentWorkerThread() { | |
225 delete this; | |
226 } | |
227 | |
228 } // namespace content | |
OLD | NEW |