[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
4 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 5 | #include "extensions/renderer/script_context_set.h" |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 6 | |
[email protected] | 6827510 | 2013-07-17 23:54:20 | [diff] [blame] | 7 | #include "base/message_loop/message_loop.h" |
[email protected] | a2ef54c | 2011-10-10 16:20:31 | [diff] [blame] | 8 | #include "content/public/renderer/render_view.h" |
[email protected] | e4452d3 | 2013-11-15 23:07:41 | [diff] [blame] | 9 | #include "extensions/common/extension.h" |
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 10 | #include "extensions/renderer/script_context.h" |
[email protected] | 885c0e9 | 2012-11-13 20:27:42 | [diff] [blame] | 11 | #include "v8/include/v8.h" |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 12 | |
[email protected] | 8fe74bf | 2012-08-07 21:08:42 | [diff] [blame] | 13 | namespace extensions { |
14 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 15 | ScriptContextSet::ScriptContextSet() { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 16 | } |
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 17 | ScriptContextSet::~ScriptContextSet() { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 18 | } |
19 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 20 | int ScriptContextSet::size() const { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 21 | return static_cast<int>(contexts_.size()); |
22 | } | ||||
23 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 24 | void ScriptContextSet::Add(ScriptContext* context) { |
[email protected] | c02cb801 | 2014-03-14 18:39:53 | [diff] [blame] | 25 | #if DCHECK_IS_ON |
26 | // It's OK to insert the same context twice, but we should only ever have | ||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 27 | // one ScriptContext per v8::Context. |
[email protected] | c02cb801 | 2014-03-14 18:39:53 | [diff] [blame] | 28 | for (ContextSet::iterator iter = contexts_.begin(); iter != contexts_.end(); |
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 29 | ++iter) { |
30 | ScriptContext* candidate = *iter; | ||||
[email protected] | c02cb801 | 2014-03-14 18:39:53 | [diff] [blame] | 31 | if (candidate != context) |
32 | DCHECK(candidate->v8_context() != context->v8_context()); | ||||
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 33 | } |
[email protected] | c02cb801 | 2014-03-14 18:39:53 | [diff] [blame] | 34 | #endif |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 35 | contexts_.insert(context); |
36 | } | ||||
37 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 38 | void ScriptContextSet::Remove(ScriptContext* context) { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 39 | if (contexts_.erase(context)) { |
[email protected] | 4f1633f | 2013-03-09 14:26:24 | [diff] [blame] | 40 | context->Invalidate(); |
[email protected] | bb024fe | 2013-05-10 21:33:26 | [diff] [blame] | 41 | base::MessageLoop::current()->DeleteSoon(FROM_HERE, context); |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 42 | } |
43 | } | ||||
44 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 45 | ScriptContextSet::ContextSet ScriptContextSet::GetAll() const { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 46 | return contexts_; |
47 | } | ||||
48 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 49 | ScriptContext* ScriptContextSet::GetCurrent() const { |
[email protected] | 95c6b301 | 2013-12-02 14:30:31 | [diff] [blame] | 50 | v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
51 | return isolate->InContext() ? GetByV8Context(isolate->GetCurrentContext()) | ||||
52 | : NULL; | ||||
[email protected] | ad6aa8f9 | 2013-06-22 15:34:16 | [diff] [blame] | 53 | } |
54 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 55 | ScriptContext* ScriptContextSet::GetCalling() const { |
[email protected] | 95c6b301 | 2013-12-02 14:30:31 | [diff] [blame] | 56 | v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
57 | v8::Local<v8::Context> calling = isolate->GetCallingContext(); | ||||
[email protected] | ad6aa8f9 | 2013-06-22 15:34:16 | [diff] [blame] | 58 | return calling.IsEmpty() ? NULL : GetByV8Context(calling); |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 59 | } |
60 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 61 | ScriptContext* ScriptContextSet::GetByV8Context( |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 62 | v8::Handle<v8::Context> v8_context) const { |
63 | for (ContextSet::const_iterator iter = contexts_.begin(); | ||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 64 | iter != contexts_.end(); |
65 | ++iter) { | ||||
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 66 | if ((*iter)->v8_context() == v8_context) |
67 | return *iter; | ||||
68 | } | ||||
69 | |||||
70 | return NULL; | ||||
71 | } | ||||
72 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 73 | void ScriptContextSet::ForEach( |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 74 | const std::string& extension_id, |
[email protected] | 68e63ea1 | 2013-06-05 05:00:54 | [diff] [blame] | 75 | content::RenderView* render_view, |
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 76 | const base::Callback<void(ScriptContext*)>& callback) const { |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 77 | // We copy the context list, because calling into javascript may modify it |
78 | // out from under us. | ||||
79 | ContextSet contexts = GetAll(); | ||||
80 | |||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 81 | for (ContextSet::iterator it = contexts.begin(); it != contexts.end(); ++it) { |
82 | ScriptContext* context = *it; | ||||
[email protected] | dd21890 | 2013-06-06 03:04:25 | [diff] [blame] | 83 | |
84 | // For the same reason as above, contexts may become invalid while we run. | ||||
85 | if (!context->is_valid()) | ||||
86 | continue; | ||||
87 | |||||
[email protected] | a76226d | 2012-04-11 07:58:29 | [diff] [blame] | 88 | if (!extension_id.empty()) { |
[email protected] | dd21890 | 2013-06-06 03:04:25 | [diff] [blame] | 89 | const Extension* extension = context->extension(); |
[email protected] | a76226d | 2012-04-11 07:58:29 | [diff] [blame] | 90 | if (!extension || (extension_id != extension->id())) |
91 | continue; | ||||
92 | } | ||||
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 93 | |
[email protected] | dd21890 | 2013-06-06 03:04:25 | [diff] [blame] | 94 | content::RenderView* context_render_view = context->GetRenderView(); |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 95 | if (!context_render_view) |
96 | continue; | ||||
97 | |||||
98 | if (render_view && render_view != context_render_view) | ||||
99 | continue; | ||||
100 | |||||
[email protected] | dd21890 | 2013-06-06 03:04:25 | [diff] [blame] | 101 | callback.Run(context); |
[email protected] | 2ee1e3a | 2011-10-04 15:04:04 | [diff] [blame] | 102 | } |
103 | } | ||||
[email protected] | 8fe74bf | 2012-08-07 21:08:42 | [diff] [blame] | 104 | |
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 105 | ScriptContextSet::ContextSet ScriptContextSet::OnExtensionUnloaded( |
[email protected] | 280055f | 2013-04-23 00:50:47 | [diff] [blame] | 106 | const std::string& extension_id) { |
[email protected] | 8c9311c | 2013-01-16 03:28:47 | [diff] [blame] | 107 | ContextSet contexts = GetAll(); |
[email protected] | 280055f | 2013-04-23 00:50:47 | [diff] [blame] | 108 | ContextSet removed; |
[email protected] | 8c9311c | 2013-01-16 03:28:47 | [diff] [blame] | 109 | |
110 | // Clean up contexts belonging to the unloaded extension. This is done so | ||||
111 | // that content scripts (which remain injected into the page) don't continue | ||||
112 | // receiving events and sending messages. | ||||
[email protected] | bcd9580f | 2014-04-17 19:17:59 | [diff] [blame^] | 113 | for (ContextSet::iterator it = contexts.begin(); it != contexts.end(); ++it) { |
[email protected] | 8c9311c | 2013-01-16 03:28:47 | [diff] [blame] | 114 | if ((*it)->extension() && (*it)->extension()->id() == extension_id) { |
115 | (*it)->DispatchOnUnloadEvent(); | ||||
[email protected] | 280055f | 2013-04-23 00:50:47 | [diff] [blame] | 116 | removed.insert(*it); |
[email protected] | 8c9311c | 2013-01-16 03:28:47 | [diff] [blame] | 117 | Remove(*it); |
118 | } | ||||
119 | } | ||||
[email protected] | 280055f | 2013-04-23 00:50:47 | [diff] [blame] | 120 | |
121 | return removed; | ||||
[email protected] | 8c9311c | 2013-01-16 03:28:47 | [diff] [blame] | 122 | } |
123 | |||||
[email protected] | 8fe74bf | 2012-08-07 21:08:42 | [diff] [blame] | 124 | } // namespace extensions |