Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: chrome/renderer/extensions/chrome_v8_context.cc

Issue 15855010: Make ExtensionMsg_MessageInvoke run a module system function rather than a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test compile Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/renderer/extensions/chrome_v8_context.h" 5 #include "chrome/renderer/extensions/chrome_v8_context.h"
6 6
7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 7 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_split.h" 9 #include "base/strings/string_split.h"
11 #include "base/values.h" 10 #include "base/values.h"
12 #include "chrome/common/extensions/api/extension_api.h" 11 #include "chrome/common/extensions/api/extension_api.h"
13 #include "chrome/common/extensions/extension.h" 12 #include "chrome/common/extensions/extension.h"
14 #include "chrome/common/extensions/extension_set.h" 13 #include "chrome/common/extensions/extension_set.h"
15 #include "chrome/common/extensions/features/base_feature_provider.h" 14 #include "chrome/common/extensions/features/base_feature_provider.h"
16 #include "chrome/renderer/extensions/chrome_v8_extension.h" 15 #include "chrome/renderer/extensions/chrome_v8_extension.h"
17 #include "chrome/renderer/extensions/module_system.h" 16 #include "chrome/renderer/extensions/module_system.h"
18 #include "chrome/renderer/extensions/user_script_slave.h" 17 #include "chrome/renderer/extensions/user_script_slave.h"
19 #include "content/public/renderer/render_view.h" 18 #include "content/public/renderer/render_view.h"
20 #include "content/public/renderer/v8_value_converter.h" 19 #include "content/public/renderer/v8_value_converter.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedMicrotaskSup pression.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
23 #include "v8/include/v8.h" 23 #include "v8/include/v8.h"
24 24
25 using content::V8ValueConverter; 25 using content::V8ValueConverter;
26 26
27 namespace extensions { 27 namespace extensions {
28 28
29 namespace { 29 namespace {
30
31 const char kChromeHidden[] = "chromeHidden"; 30 const char kChromeHidden[] = "chromeHidden";
32 const char kValidateCallbacks[] = "validateCallbacks";
33 const char kValidateAPI[] = "validateAPI";
34
35 } // namespace 31 } // namespace
36 32
37 ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context, 33 ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context,
38 WebKit::WebFrame* web_frame, 34 WebKit::WebFrame* web_frame,
39 const Extension* extension, 35 const Extension* extension,
40 Feature::Context context_type) 36 Feature::Context context_type)
41 : v8_context_(v8_context), 37 : v8_context_(v8_context),
42 web_frame_(web_frame), 38 web_frame_(web_frame),
43 extension_(extension), 39 extension_(extension),
44 context_type_(context_type) { 40 context_type_(context_type) {
45 VLOG(1) << "Created context:\n" 41 VLOG(1) << "Created context:\n"
46 << " extension id: " << GetExtensionID() << "\n" 42 << " extension id: " << GetExtensionID() << "\n"
47 << " frame: " << web_frame_ << "\n" 43 << " frame: " << web_frame_ << "\n"
48 << " context type: " << GetContextTypeDescription(); 44 << " context type: " << GetContextTypeDescription();
49 } 45 }
50 46
51 ChromeV8Context::~ChromeV8Context() { 47 ChromeV8Context::~ChromeV8Context() {
52 VLOG(1) << "Destroyed context for extension\n" 48 VLOG(1) << "Destroyed context for extension\n"
53 << " extension id: " << GetExtensionID(); 49 << " extension id: " << GetExtensionID();
54 Invalidate(); 50 Invalidate();
55 } 51 }
56 52
57 void ChromeV8Context::Invalidate() { 53 void ChromeV8Context::Invalidate() {
58 if (v8_context_.get().IsEmpty()) 54 if (!is_valid())
59 return; 55 return;
60 if (module_system_) 56 if (module_system_)
61 module_system_->Invalidate(); 57 module_system_->Invalidate();
62 web_frame_ = NULL; 58 web_frame_ = NULL;
63 v8_context_.reset(); 59 v8_context_.reset();
64 } 60 }
65 61
66 std::string ChromeV8Context::GetExtensionID() { 62 std::string ChromeV8Context::GetExtensionID() {
67 return extension_.get() ? extension_->id() : std::string(); 63 return extension_.get() ? extension_->id() : std::string();
68 } 64 }
69 65
70 // static 66 // static
71 v8::Handle<v8::Value> ChromeV8Context::GetOrCreateChromeHidden( 67 v8::Handle<v8::Value> ChromeV8Context::GetOrCreateChromeHidden(
72 v8::Handle<v8::Context> context) { 68 v8::Handle<v8::Context> context) {
73 v8::Local<v8::Object> global = context->Global(); 69 v8::Local<v8::Object> global = context->Global();
74 v8::Local<v8::Value> hidden = global->GetHiddenValue( 70 v8::Local<v8::Value> hidden = global->GetHiddenValue(
75 v8::String::New(kChromeHidden)); 71 v8::String::New(kChromeHidden));
76 72
77 if (hidden.IsEmpty() || hidden->IsUndefined()) { 73 if (hidden.IsEmpty() || hidden->IsUndefined()) {
78 hidden = v8::Object::New(); 74 hidden = v8::Object::New();
79 global->SetHiddenValue(v8::String::New(kChromeHidden), hidden); 75 global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
80
81 if (DCHECK_IS_ON()) {
82 // Tell bindings.js to validate callbacks and events against their schema
83 // definitions.
84 v8::Local<v8::Object>::Cast(hidden)->Set(
85 v8::String::New(kValidateCallbacks), v8::True());
86 // Tell bindings.js to validate API for ambiguity.
87 v8::Local<v8::Object>::Cast(hidden)->Set(
88 v8::String::New(kValidateAPI), v8::True());
89 }
90 } 76 }
91 77
92 DCHECK(hidden->IsObject()); 78 DCHECK(hidden->IsObject());
93 return v8::Local<v8::Object>::Cast(hidden); 79 return v8::Local<v8::Object>::Cast(hidden);
94 } 80 }
95 81
96 v8::Handle<v8::Value> ChromeV8Context::GetChromeHidden() const { 82 v8::Handle<v8::Value> ChromeV8Context::GetChromeHidden() const {
97 v8::Local<v8::Object> global = v8_context_->Global(); 83 v8::Local<v8::Object> global = v8_context_->Global();
98 return global->GetHiddenValue(v8::String::New(kChromeHidden)); 84 return global->GetHiddenValue(v8::String::New(kChromeHidden));
99 } 85 }
100 86
101 content::RenderView* ChromeV8Context::GetRenderView() const { 87 content::RenderView* ChromeV8Context::GetRenderView() const {
102 if (web_frame_ && web_frame_->view()) 88 if (web_frame_ && web_frame_->view())
103 return content::RenderView::FromWebView(web_frame_->view()); 89 return content::RenderView::FromWebView(web_frame_->view());
104 else 90 else
105 return NULL; 91 return NULL;
106 } 92 }
107 93
108 bool ChromeV8Context::CallChromeHiddenMethod( 94 v8::Local<v8::Value> ChromeV8Context::CallFunction(
109 const std::string& function_name, 95 v8::Handle<v8::Function> function,
110 int argc, 96 int argc,
111 v8::Handle<v8::Value>* argv, 97 v8::Handle<v8::Value> argv[]) const {
112 v8::Handle<v8::Value>* result) const { 98 v8::HandleScope handle_scope;
113 // ChromeV8ContextSet calls Invalidate() and then schedules a task to delete 99 WebKit::WebScopedMicrotaskSuppression suppression;
114 // this object. This check prevents a race from attempting to execute script 100 if (!is_valid())
115 // on a NULL web_frame_. 101 return handle_scope.Close(v8::Undefined());
102
103 v8::Handle<v8::Object> global = v8_context()->Global();
116 if (!web_frame_) 104 if (!web_frame_)
117 return false; 105 return handle_scope.Close(function->Call(global, argc, argv));
118 106 return handle_scope.Close(
119 v8::Context::Scope context_scope(v8_context_.get());
120
121 // Look up the function name, which may be a sub-property like
122 // "Port.dispatchOnMessage" in the hidden global variable.
123 v8::Local<v8::Value> value = v8::Local<v8::Value>::New(GetChromeHidden());
124 if (value.IsEmpty())
125 return false;
126
127 std::vector<std::string> components;
128 base::SplitStringDontTrim(function_name, '.', &components);
129 for (size_t i = 0; i < components.size(); ++i) {
130 if (!value.IsEmpty() && value->IsObject()) {
131 value = v8::Local<v8::Object>::Cast(value)->Get(
132 v8::String::New(components[i].c_str()));
133 }
134 }
135
136 if (value.IsEmpty() || !value->IsFunction()) {
137 VLOG(1) << "Could not execute chrome hidden method: " << function_name;
138 return false;
139 }
140
141 TRACE_EVENT1("v8", "v8.callChromeHiddenMethod",
142 "function_name", function_name);
143
144 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value);
145 v8::Handle<v8::Value> result_temp =
146 web_frame_->callFunctionEvenIfScriptDisabled(function, 107 web_frame_->callFunctionEvenIfScriptDisabled(function,
147 v8::Object::New(), 108 global,
148 argc, 109 argc,
149 argv); 110 argv));
150 if (result)
151 *result = result_temp;
152
153 return true;
154 } 111 }
155 112
156 bool ChromeV8Context::IsAnyFeatureAvailableToContext( 113 bool ChromeV8Context::IsAnyFeatureAvailableToContext(
157 const std::string& api_name) { 114 const std::string& api_name) {
158 return ExtensionAPI::GetSharedInstance()->IsAnyFeatureAvailableToContext( 115 return ExtensionAPI::GetSharedInstance()->IsAnyFeatureAvailableToContext(
159 api_name, 116 api_name,
160 context_type_, 117 context_type_,
161 UserScriptSlave::GetDataSourceURLForFrame(web_frame_)); 118 UserScriptSlave::GetDataSourceURLForFrame(web_frame_));
162 } 119 }
163 120
164 Feature::Availability ChromeV8Context::GetAvailability( 121 Feature::Availability ChromeV8Context::GetAvailability(
165 const std::string& api_name) { 122 const std::string& api_name) {
166 return ExtensionAPI::GetSharedInstance()->IsAvailable( 123 return ExtensionAPI::GetSharedInstance()->IsAvailable(
167 api_name, 124 api_name,
168 extension_.get(), 125 extension_.get(),
169 context_type_, 126 context_type_,
170 UserScriptSlave::GetDataSourceURLForFrame(web_frame_)); 127 UserScriptSlave::GetDataSourceURLForFrame(web_frame_));
171 } 128 }
172 129
173 void ChromeV8Context::DispatchOnUnloadEvent() { 130 void ChromeV8Context::DispatchOnUnloadEvent() {
174 v8::HandleScope handle_scope; 131 module_system_->CallModuleMethod("unload_event", "dispatch");
175 CallChromeHiddenMethod("dispatchOnUnload", 0, NULL, NULL);
176 } 132 }
177 133
178 std::string ChromeV8Context::GetContextTypeDescription() { 134 std::string ChromeV8Context::GetContextTypeDescription() {
179 switch (context_type_) { 135 switch (context_type_) {
180 case Feature::UNSPECIFIED_CONTEXT: return "UNSPECIFIED"; 136 case Feature::UNSPECIFIED_CONTEXT: return "UNSPECIFIED";
181 case Feature::BLESSED_EXTENSION_CONTEXT: return "BLESSED_EXTENSION"; 137 case Feature::BLESSED_EXTENSION_CONTEXT: return "BLESSED_EXTENSION";
182 case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION"; 138 case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION";
183 case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT"; 139 case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT";
184 case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE"; 140 case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE";
185 } 141 }
(...skipping 14 matching lines...) Expand all
200 156
201 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 157 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
202 v8::Handle<v8::Value> argv[] = { 158 v8::Handle<v8::Value> argv[] = {
203 v8::Integer::New(request_id), 159 v8::Integer::New(request_id),
204 v8::String::New(name.c_str()), 160 v8::String::New(name.c_str()),
205 v8::Boolean::New(success), 161 v8::Boolean::New(success),
206 converter->ToV8Value(&response, v8_context_.get()), 162 converter->ToV8Value(&response, v8_context_.get()),
207 v8::String::New(error.c_str()) 163 v8::String::New(error.c_str())
208 }; 164 };
209 165
210 v8::Handle<v8::Value> retval; 166 v8::Handle<v8::Value> retval = module_system_->CallModuleMethod(
211 CHECK(CallChromeHiddenMethod("handleResponse", arraysize(argv), argv, 167 "sendRequest", "handleResponse", arraysize(argv), argv);
212 &retval)); 168
213 // In debug, the js will validate the callback parameters and return a 169 // In debug, the js will validate the callback parameters and return a
214 // string if a validation error has occured. 170 // string if a validation error has occured.
215 if (DCHECK_IS_ON()) { 171 if (DCHECK_IS_ON()) {
216 if (!retval.IsEmpty() && !retval->IsUndefined()) { 172 if (!retval.IsEmpty() && !retval->IsUndefined()) {
217 std::string error = *v8::String::AsciiValue(retval); 173 std::string error = *v8::String::AsciiValue(retval);
218 DCHECK(false) << error; 174 DCHECK(false) << error;
219 } 175 }
220 } 176 }
221 } 177 }
222 178
179 bool ChromeV8Context::is_valid() const {
180 return !v8_context_.get().IsEmpty();
181 }
182
223 } // namespace extensions 183 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/chrome_v8_context.h ('k') | chrome/renderer/extensions/chrome_v8_context_set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698