OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/npapi/np_channel_base.h" | 5 #include "content/child/npapi/np_channel_base.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
11 #include "base/files/scoped_file.h" | 11 #include "base/files/scoped_file.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "base/threading/thread_local.h" | 14 #include "base/threading/thread_local.h" |
16 #include "build/build_config.h" | 15 #include "build/build_config.h" |
17 #include "ipc/ipc_sync_message.h" | 16 #include "ipc/ipc_sync_message.h" |
18 | 17 |
19 #if defined(OS_POSIX) | 18 #if defined(OS_POSIX) |
20 #include "base/files/file_util.h" | 19 #include "base/files/file_util.h" |
21 #include "ipc/ipc_channel_posix.h" | 20 #include "ipc/ipc_channel_posix.h" |
22 #endif | 21 #endif |
23 | 22 |
24 namespace content { | 23 namespace content { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 ++iter) { | 116 ++iter) { |
118 iter->second->Send(new IPC::Message(*message)); | 117 iter->second->Send(new IPC::Message(*message)); |
119 } | 118 } |
120 delete message; | 119 delete message; |
121 } | 120 } |
122 | 121 |
123 NPChannelBase::NPChannelBase() | 122 NPChannelBase::NPChannelBase() |
124 : mode_(IPC::Channel::MODE_NONE), | 123 : mode_(IPC::Channel::MODE_NONE), |
125 non_npobject_count_(0), | 124 non_npobject_count_(0), |
126 peer_pid_(0), | 125 peer_pid_(0), |
127 in_remove_route_(false), | |
128 default_owner_(NULL), | |
129 channel_valid_(false), | 126 channel_valid_(false), |
130 in_unblock_dispatch_(0), | 127 in_unblock_dispatch_(0), |
131 send_unblocking_only_during_unblock_dispatch_(false) { | 128 send_unblocking_only_during_unblock_dispatch_(false) { |
132 } | 129 } |
133 | 130 |
134 NPChannelBase::~NPChannelBase() { | 131 NPChannelBase::~NPChannelBase() { |
135 // TODO(wez): Establish why these would ever be non-empty at teardown. | |
136 //DCHECK(npobject_listeners_.empty()); | |
137 //DCHECK(proxy_map_.empty()); | |
138 //DCHECK(stub_map_.empty()); | |
139 DCHECK(owner_to_route_.empty()); | |
140 DCHECK(route_to_owner_.empty()); | |
141 } | 132 } |
142 | 133 |
143 NPChannelBase* NPChannelBase::GetCurrentChannel() { | 134 NPChannelBase* NPChannelBase::GetCurrentChannel() { |
144 return GetChannelGlobals()->current_channel.get(); | 135 return GetChannelGlobals()->current_channel.get(); |
145 } | 136 } |
146 | 137 |
147 void NPChannelBase::CleanupChannels() { | 138 void NPChannelBase::CleanupChannels() { |
148 // Make a copy of the references as we can't iterate the map since items will | 139 // Make a copy of the references as we can't iterate the map since items will |
149 // be removed from it as we clean them up. | 140 // be removed from it as we clean them up. |
150 std::vector<scoped_refptr<NPChannelBase> > channels; | 141 std::vector<scoped_refptr<NPChannelBase> > channels; |
151 for (ChannelMap::const_iterator iter = GetChannelMap()->begin(); | 142 for (ChannelMap::const_iterator iter = GetChannelMap()->begin(); |
152 iter != GetChannelMap()->end(); | 143 iter != GetChannelMap()->end(); |
153 ++iter) { | 144 ++iter) { |
154 channels.push_back(iter->second); | 145 channels.push_back(iter->second); |
155 } | 146 } |
156 | 147 |
157 for (size_t i = 0; i < channels.size(); ++i) | 148 for (size_t i = 0; i < channels.size(); ++i) |
158 channels[i]->CleanUp(); | 149 channels[i]->CleanUp(); |
159 | 150 |
160 // This will clean up channels added to the map for which subsequent | 151 // This will clean up channels added to the map for which subsequent |
161 // AddRoute wasn't called | 152 // AddRoute wasn't called |
162 GetChannelMap()->clear(); | 153 GetChannelMap()->clear(); |
163 } | 154 } |
164 | 155 |
165 NPObjectBase* NPChannelBase::GetNPObjectListenerForRoute(int route_id) { | |
166 ListenerMap::iterator iter = npobject_listeners_.find(route_id); | |
167 if (iter == npobject_listeners_.end()) { | |
168 DLOG(WARNING) << "Invalid route id passed in:" << route_id; | |
169 return NULL; | |
170 } | |
171 return iter->second; | |
172 } | |
173 | |
174 base::WaitableEvent* NPChannelBase::GetModalDialogEvent(int render_view_id) { | 156 base::WaitableEvent* NPChannelBase::GetModalDialogEvent(int render_view_id) { |
175 return NULL; | 157 return NULL; |
176 } | 158 } |
177 | 159 |
178 bool NPChannelBase::Init(base::SingleThreadTaskRunner* ipc_task_runner, | 160 bool NPChannelBase::Init(base::SingleThreadTaskRunner* ipc_task_runner, |
179 bool create_pipe_now, | 161 bool create_pipe_now, |
180 base::WaitableEvent* shutdown_event) { | 162 base::WaitableEvent* shutdown_event) { |
181 #if defined(OS_POSIX) | 163 #if defined(OS_POSIX) |
182 // Attempting to initialize with an invalid channel handle. | 164 // Attempting to initialize with an invalid channel handle. |
183 // See http://crbug.com/97285 for details. | 165 // See http://crbug.com/97285 for details. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if (message.should_unblock()) | 227 if (message.should_unblock()) |
246 in_unblock_dispatch_--; | 228 in_unblock_dispatch_--; |
247 | 229 |
248 return handled; | 230 return handled; |
249 } | 231 } |
250 | 232 |
251 void NPChannelBase::OnChannelConnected(int32_t peer_pid) { | 233 void NPChannelBase::OnChannelConnected(int32_t peer_pid) { |
252 peer_pid_ = peer_pid; | 234 peer_pid_ = peer_pid; |
253 } | 235 } |
254 | 236 |
255 void NPChannelBase::AddRoute(int route_id, | 237 void NPChannelBase::AddRoute(int route_id, IPC::Listener* listener) { |
256 IPC::Listener* listener, | 238 non_npobject_count_++; |
257 NPObjectBase* npobject) { | |
258 if (npobject) { | |
259 npobject_listeners_[route_id] = npobject; | |
260 } else { | |
261 non_npobject_count_++; | |
262 } | |
263 | |
264 router_.AddRoute(route_id, listener); | 239 router_.AddRoute(route_id, listener); |
265 } | 240 } |
266 | 241 |
267 void NPChannelBase::RemoveRoute(int route_id) { | 242 void NPChannelBase::RemoveRoute(int route_id) { |
268 router_.RemoveRoute(route_id); | 243 router_.RemoveRoute(route_id); |
269 | 244 |
270 ListenerMap::iterator iter = npobject_listeners_.find(route_id); | |
271 if (iter != npobject_listeners_.end()) { | |
272 // This was an NPObject proxy or stub, it's not involved in the refcounting. | |
273 | |
274 // If this RemoveRoute call from the NPObject is a result of us calling | |
275 // OnChannelError below, don't call erase() here because that'll corrupt | |
276 // the iterator below. | |
277 if (in_remove_route_) { | |
278 iter->second = NULL; | |
279 } else { | |
280 npobject_listeners_.erase(iter); | |
281 } | |
282 | |
283 return; | |
284 } | |
285 | |
286 non_npobject_count_--; | 245 non_npobject_count_--; |
287 DCHECK(non_npobject_count_ >= 0); | 246 DCHECK(non_npobject_count_ >= 0); |
288 | 247 |
289 if (!non_npobject_count_) { | 248 if (!non_npobject_count_) { |
290 base::AutoReset<bool> auto_reset_in_remove_route(&in_remove_route_, true); | |
291 for (ListenerMap::iterator npobj_iter = npobject_listeners_.begin(); | |
292 npobj_iter != npobject_listeners_.end(); ++npobj_iter) { | |
293 if (npobj_iter->second) { | |
294 npobj_iter->second->GetChannelListener()->OnChannelError(); | |
295 } | |
296 } | |
297 | |
298 for (ChannelMap::iterator iter = GetChannelMap()->begin(); | 249 for (ChannelMap::iterator iter = GetChannelMap()->begin(); |
299 iter != GetChannelMap()->end(); ++iter) { | 250 iter != GetChannelMap()->end(); ++iter) { |
300 if (iter->second.get() == this) { | 251 if (iter->second.get() == this) { |
301 GetChannelMap()->erase(iter); | 252 GetChannelMap()->erase(iter); |
302 return; | 253 return; |
303 } | 254 } |
304 } | 255 } |
305 | 256 |
306 NOTREACHED(); | 257 NOTREACHED(); |
307 } | 258 } |
(...skipping 16 matching lines...) Expand all Loading... |
324 iter != GetChannelMap()->end(); ++iter) { | 275 iter != GetChannelMap()->end(); ++iter) { |
325 if (iter->second.get() == this) { | 276 if (iter->second.get() == this) { |
326 // Insert new element before invalidating |iter|. | 277 // Insert new element before invalidating |iter|. |
327 (*GetChannelMap())[iter->first + "-error"] = iter->second; | 278 (*GetChannelMap())[iter->first + "-error"] = iter->second; |
328 GetChannelMap()->erase(iter); | 279 GetChannelMap()->erase(iter); |
329 break; | 280 break; |
330 } | 281 } |
331 } | 282 } |
332 } | 283 } |
333 | 284 |
334 void NPChannelBase::AddMappingForNPObjectProxy(int route_id, | |
335 NPObject* object) { | |
336 proxy_map_[route_id] = object; | |
337 } | |
338 | |
339 void NPChannelBase::RemoveMappingForNPObjectProxy(int route_id) { | |
340 proxy_map_.erase(route_id); | |
341 } | |
342 | |
343 void NPChannelBase::AddMappingForNPObjectStub(int route_id, | |
344 NPObject* object) { | |
345 DCHECK(object != NULL); | |
346 stub_map_[object] = route_id; | |
347 } | |
348 | |
349 void NPChannelBase::RemoveMappingForNPObjectStub(int route_id, | |
350 NPObject* object) { | |
351 DCHECK(object != NULL); | |
352 stub_map_.erase(object); | |
353 } | |
354 | |
355 void NPChannelBase::AddMappingForNPObjectOwner(int route_id, | |
356 struct _NPP* owner) { | |
357 DCHECK(owner != NULL); | |
358 route_to_owner_[route_id] = owner; | |
359 owner_to_route_[owner] = route_id; | |
360 } | |
361 | |
362 void NPChannelBase::SetDefaultNPObjectOwner(struct _NPP* owner) { | |
363 DCHECK(owner != NULL); | |
364 default_owner_ = owner; | |
365 } | |
366 | |
367 void NPChannelBase::RemoveMappingForNPObjectOwner(int route_id) { | |
368 DCHECK(route_to_owner_.find(route_id) != route_to_owner_.end()); | |
369 owner_to_route_.erase(route_to_owner_[route_id]); | |
370 route_to_owner_.erase(route_id); | |
371 } | |
372 | |
373 NPObject* NPChannelBase::GetExistingNPObjectProxy(int route_id) { | |
374 ProxyMap::iterator iter = proxy_map_.find(route_id); | |
375 return iter != proxy_map_.end() ? iter->second : NULL; | |
376 } | |
377 | |
378 int NPChannelBase::GetExistingRouteForNPObjectStub(NPObject* npobject) { | |
379 StubMap::iterator iter = stub_map_.find(npobject); | |
380 return iter != stub_map_.end() ? iter->second : MSG_ROUTING_NONE; | |
381 } | |
382 | |
383 NPP NPChannelBase::GetExistingNPObjectOwner(int route_id) { | |
384 RouteToOwnerMap::iterator iter = route_to_owner_.find(route_id); | |
385 return iter != route_to_owner_.end() ? iter->second : default_owner_; | |
386 } | |
387 | |
388 int NPChannelBase::GetExistingRouteForNPObjectOwner(NPP owner) { | |
389 OwnerToRouteMap::iterator iter = owner_to_route_.find(owner); | |
390 return iter != owner_to_route_.end() ? iter->second : MSG_ROUTING_NONE; | |
391 } | |
392 | |
393 } // namespace content | 285 } // namespace content |
OLD | NEW |