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

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

Issue 11571014: Lazy load chrome.* APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: windows interactive_ui_tests fix Created 7 years, 9 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" 7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_split.h" 9 #include "base/string_split.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "chrome/common/extensions/api/extension_api.h" 11 #include "chrome/common/extensions/api/extension_api.h"
12 #include "chrome/common/extensions/extension.h" 12 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/extensions/extension_set.h" 13 #include "chrome/common/extensions/extension_set.h"
14 #include "chrome/renderer/extensions/chrome_v8_extension.h" 14 #include "chrome/renderer/extensions/chrome_v8_extension.h"
15 #include "chrome/renderer/extensions/module_system.h"
15 #include "chrome/renderer/extensions/user_script_slave.h" 16 #include "chrome/renderer/extensions/user_script_slave.h"
16 #include "content/public/renderer/render_view.h" 17 #include "content/public/renderer/render_view.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
19 #include "v8/include/v8.h" 20 #include "v8/include/v8.h"
20 21
21 namespace extensions { 22 namespace extensions {
22 23
23 namespace { 24 namespace {
24 25
25 const char kChromeHidden[] = "chromeHidden"; 26 const char kChromeHidden[] = "chromeHidden";
27 const char kUnavailableMessage[] = "You do not have permission to access this "
28 "API. Ensure that the required permission "
29 "or manifest property is included in your "
30 "manifest.json.";
26 31
27 const char kValidateCallbacks[] = "validateCallbacks"; 32 const char kValidateCallbacks[] = "validateCallbacks";
28 const char kValidateAPI[] = "validateAPI"; 33 const char kValidateAPI[] = "validateAPI";
29 34
30 } // namespace 35 } // namespace
31 36
32 ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context, 37 ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context,
33 WebKit::WebFrame* web_frame, 38 WebKit::WebFrame* web_frame,
34 const Extension* extension, 39 const Extension* extension,
35 Feature::Context context_type) 40 Feature::Context context_type)
36 : v8_context_(v8::Persistent<v8::Context>::New(v8_context->GetIsolate(), 41 : v8_context_(v8::Persistent<v8::Context>::New(v8_context->GetIsolate(),
37 v8_context)), 42 v8_context)),
38 web_frame_(web_frame), 43 web_frame_(web_frame),
39 extension_(extension), 44 extension_(extension),
40 context_type_(context_type) { 45 context_type_(context_type),
46 available_extension_apis_initialized_(false) {
41 VLOG(1) << "Created context:\n" 47 VLOG(1) << "Created context:\n"
42 << " extension id: " << GetExtensionID() << "\n" 48 << " extension id: " << GetExtensionID() << "\n"
43 << " frame: " << web_frame_ << "\n" 49 << " frame: " << web_frame_ << "\n"
44 << " context type: " << GetContextTypeDescription(); 50 << " context type: " << GetContextTypeDescription();
45 } 51 }
46 52
47 ChromeV8Context::~ChromeV8Context() { 53 ChromeV8Context::~ChromeV8Context() {
48 VLOG(1) << "Destroyed context for extension\n" 54 VLOG(1) << "Destroyed context for extension\n"
49 << " extension id: " << GetExtensionID(); 55 << " extension id: " << GetExtensionID();
50 v8_context_.Dispose(v8_context_->GetIsolate()); 56 v8_context_.Dispose(v8_context_->GetIsolate());
51 } 57 }
52 58
59 void ChromeV8Context::Invalidate() {
60 if (module_system_)
61 module_system_->Invalidate();
62 web_frame_ = NULL;
63 }
64
53 std::string ChromeV8Context::GetExtensionID() { 65 std::string ChromeV8Context::GetExtensionID() {
54 return extension_ ? extension_->id() : ""; 66 return extension_ ? extension_->id() : "";
55 } 67 }
56 68
57 // static 69 // static
58 v8::Handle<v8::Value> ChromeV8Context::GetOrCreateChromeHidden( 70 v8::Handle<v8::Value> ChromeV8Context::GetOrCreateChromeHidden(
59 v8::Handle<v8::Context> context) { 71 v8::Handle<v8::Context> context) {
60 v8::Local<v8::Object> global = context->Global(); 72 v8::Local<v8::Object> global = context->Global();
61 v8::Local<v8::Value> hidden = global->GetHiddenValue( 73 v8::Local<v8::Value> hidden = global->GetHiddenValue(
62 v8::String::New(kChromeHidden)); 74 v8::String::New(kChromeHidden));
63 75
64 if (hidden.IsEmpty() || hidden->IsUndefined()) { 76 if (hidden.IsEmpty() || hidden->IsUndefined()) {
65 hidden = v8::Object::New(); 77 hidden = v8::Object::New();
66 global->SetHiddenValue(v8::String::New(kChromeHidden), hidden); 78 global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
67 79
68 if (DCHECK_IS_ON()) { 80 if (DCHECK_IS_ON()) {
69 // Tell schema_generated_bindings.js to validate callbacks and events 81 // Tell bindings.js to validate callbacks and events against their schema
70 // against their schema definitions. 82 // definitions.
71 v8::Local<v8::Object>::Cast(hidden)->Set( 83 v8::Local<v8::Object>::Cast(hidden)->Set(
72 v8::String::New(kValidateCallbacks), v8::True()); 84 v8::String::New(kValidateCallbacks), v8::True());
73 // Tell schema_generated_bindings.js to validate API for ambiguity. 85 // Tell bindings.js to validate API for ambiguity.
74 v8::Local<v8::Object>::Cast(hidden)->Set( 86 v8::Local<v8::Object>::Cast(hidden)->Set(
75 v8::String::New(kValidateAPI), v8::True()); 87 v8::String::New(kValidateAPI), v8::True());
76 } 88 }
77 } 89 }
78 90
79 DCHECK(hidden->IsObject()); 91 DCHECK(hidden->IsObject());
80 return v8::Local<v8::Object>::Cast(hidden); 92 return v8::Local<v8::Object>::Cast(hidden);
81 } 93 }
82 94
83 v8::Handle<v8::Value> ChromeV8Context::GetChromeHidden() const { 95 v8::Handle<v8::Value> ChromeV8Context::GetChromeHidden() const {
84 v8::Local<v8::Object> global = v8_context_->Global(); 96 v8::Local<v8::Object> global = v8_context_->Global();
85 return global->GetHiddenValue(v8::String::New(kChromeHidden)); 97 return global->GetHiddenValue(v8::String::New(kChromeHidden));
86 } 98 }
87 99
88 content::RenderView* ChromeV8Context::GetRenderView() const { 100 content::RenderView* ChromeV8Context::GetRenderView() const {
89 if (web_frame_ && web_frame_->view()) 101 if (web_frame_ && web_frame_->view())
90 return content::RenderView::FromWebView(web_frame_->view()); 102 return content::RenderView::FromWebView(web_frame_->view());
91 else 103 else
92 return NULL; 104 return NULL;
93 } 105 }
94 106
95 bool ChromeV8Context::CallChromeHiddenMethod( 107 bool ChromeV8Context::CallChromeHiddenMethod(
96 const std::string& function_name, 108 const std::string& function_name,
97 int argc, 109 int argc,
98 v8::Handle<v8::Value>* argv, 110 v8::Handle<v8::Value>* argv,
99 v8::Handle<v8::Value>* result) const { 111 v8::Handle<v8::Value>* result) const {
100 v8::Context::Scope context_scope(v8_context_); 112 v8::Context::Scope context_scope(v8_context_);
101 113
102 // ChromeV8ContextSet calls clear_web_frame() and then schedules a task to 114 // ChromeV8ContextSet calls Invalidate() and then schedules a task to delete
103 // delete this object. This check prevents a race from attempting to execute 115 // this object. This check prevents a race from attempting to execute script
104 // script on a NULL web_frame_. 116 // on a NULL web_frame_.
105 if (!web_frame_) 117 if (!web_frame_)
106 return false; 118 return false;
107 119
108 // Look up the function name, which may be a sub-property like 120 // Look up the function name, which may be a sub-property like
109 // "Port.dispatchOnMessage" in the hidden global variable. 121 // "Port.dispatchOnMessage" in the hidden global variable.
110 v8::Local<v8::Value> value = v8::Local<v8::Value>::New(GetChromeHidden()); 122 v8::Local<v8::Value> value = v8::Local<v8::Value>::New(GetChromeHidden());
111 if (value.IsEmpty()) 123 if (value.IsEmpty())
112 return false; 124 return false;
113 125
114 std::vector<std::string> components; 126 std::vector<std::string> components;
(...skipping 19 matching lines...) Expand all
134 v8::Object::New(), 146 v8::Object::New(),
135 argc, 147 argc,
136 argv); 148 argv);
137 if (result) 149 if (result)
138 *result = result_temp; 150 *result = result_temp;
139 151
140 return true; 152 return true;
141 } 153 }
142 154
143 const std::set<std::string>& ChromeV8Context::GetAvailableExtensionAPIs() { 155 const std::set<std::string>& ChromeV8Context::GetAvailableExtensionAPIs() {
144 if (!available_extension_apis_.get()) { 156 if (!available_extension_apis_initialized_) {
145 available_extension_apis_ = 157 available_extension_apis_ =
146 ExtensionAPI::GetSharedInstance()->GetAPIsForContext( 158 ExtensionAPI::GetSharedInstance()->GetAPIsForContext(
147 context_type_, 159 context_type_,
148 extension_, 160 extension_,
149 UserScriptSlave::GetDataSourceURLForFrame( 161 UserScriptSlave::GetDataSourceURLForFrame(web_frame_));
150 web_frame_)).Pass(); 162 available_extension_apis_initialized_ = true;
151 } 163 }
152 return *(available_extension_apis_.get()); 164 return available_extension_apis_;
165 }
166
167 Feature::Availability ChromeV8Context::GetAvailability(
168 const std::string& api_name) {
169 const std::set<std::string>& available_apis = GetAvailableExtensionAPIs();
170
171 // TODO(cduvall/kalman): Switch to ExtensionAPI::IsAvailable() once Features
172 // are complete.
173 if (available_apis.find(api_name) != available_apis.end())
174 return Feature::CreateAvailability(Feature::IS_AVAILABLE, "");
175
176 return Feature::CreateAvailability(Feature::INVALID_CONTEXT,
177 kUnavailableMessage);
153 } 178 }
154 179
155 void ChromeV8Context::DispatchOnLoadEvent(bool is_incognito_process, 180 void ChromeV8Context::DispatchOnLoadEvent(bool is_incognito_process,
156 int manifest_version) { 181 int manifest_version) {
157 v8::HandleScope handle_scope; 182 v8::HandleScope handle_scope;
158 v8::Handle<v8::Value> argv[] = { 183 v8::Handle<v8::Value> argv[] = {
159 v8::String::New(GetExtensionID().c_str()), 184 v8::String::New(GetExtensionID().c_str()),
160 v8::String::New(GetContextTypeDescription().c_str()), 185 v8::String::New(GetContextTypeDescription().c_str()),
161 v8::Boolean::New(is_incognito_process), 186 v8::Boolean::New(is_incognito_process),
162 v8::Integer::New(manifest_version), 187 v8::Integer::New(manifest_version),
(...skipping 12 matching lines...) Expand all
175 case Feature::BLESSED_EXTENSION_CONTEXT: return "BLESSED_EXTENSION"; 200 case Feature::BLESSED_EXTENSION_CONTEXT: return "BLESSED_EXTENSION";
176 case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION"; 201 case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION";
177 case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT"; 202 case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT";
178 case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE"; 203 case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE";
179 } 204 }
180 NOTREACHED(); 205 NOTREACHED();
181 return ""; 206 return "";
182 } 207 }
183 208
184 } // namespace extensions 209 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698