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

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

Issue 8540012: Enable extension APIs for content scripts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 1 month 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/extension_process_bindings.h" 5 #include "chrome/renderer/extensions/schema_generated_bindings.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/json/json_reader.h" 14 #include "base/json/json_reader.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
17 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
18 #include "base/string_util.h" 18 #include "base/string_util.h"
19 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
20 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_action.h" 21 #include "chrome/common/extensions/extension_action.h"
22 #include "chrome/common/extensions/extension_constants.h" 22 #include "chrome/common/extensions/extension_constants.h"
23 #include "chrome/common/extensions/extension_messages.h" 23 #include "chrome/common/extensions/extension_messages.h"
24 #include "chrome/common/extensions/extension_set.h" 24 #include "chrome/common/extensions/extension_set.h"
25 #include "chrome/common/extensions/url_pattern.h" 25 #include "chrome/common/extensions/url_pattern.h"
26 #include "chrome/common/extensions/api/extension_api.h"
26 #include "chrome/common/render_messages.h" 27 #include "chrome/common/render_messages.h"
27 #include "chrome/common/url_constants.h" 28 #include "chrome/common/url_constants.h"
28 #include "chrome/common/chrome_view_types.h" 29 #include "chrome/common/chrome_view_types.h"
29 #include "content/public/renderer/render_view.h" 30 #include "content/public/renderer/render_view.h"
30 #include "content/public/renderer/render_view_visitor.h" 31 #include "content/public/renderer/render_view_visitor.h"
31 #include "chrome/renderer/chrome_render_process_observer.h" 32 #include "chrome/renderer/chrome_render_process_observer.h"
32 #include "chrome/renderer/extensions/chrome_v8_context.h" 33 #include "chrome/renderer/extensions/chrome_v8_context.h"
33 #include "chrome/renderer/extensions/chrome_v8_context_set.h" 34 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
34 #include "chrome/renderer/extensions/chrome_v8_extension.h" 35 #include "chrome/renderer/extensions/chrome_v8_extension.h"
35 #include "chrome/renderer/extensions/event_bindings.h" 36 #include "chrome/renderer/extensions/event_bindings.h"
36 #include "chrome/renderer/extensions/extension_dispatcher.h" 37 #include "chrome/renderer/extensions/extension_dispatcher.h"
37 #include "chrome/renderer/extensions/extension_helper.h" 38 #include "chrome/renderer/extensions/extension_helper.h"
38 #include "chrome/renderer/extensions/renderer_extension_bindings.h" 39 #include "chrome/renderer/extensions/miscellaneous_bindings.h"
39 #include "chrome/renderer/extensions/user_script_slave.h" 40 #include "chrome/renderer/extensions/user_script_slave.h"
40 #include "chrome/renderer/static_v8_external_string_resource.h"
41 #include "content/public/renderer/render_view.h" 41 #include "content/public/renderer/render_view.h"
42 #include "content/public/renderer/v8_value_converter.h"
42 #include "grit/common_resources.h" 43 #include "grit/common_resources.h"
43 #include "grit/renderer_resources.h" 44 #include "grit/renderer_resources.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBlob.h" 45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBlob.h"
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 48 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
48 #include "third_party/skia/include/core/SkBitmap.h" 49 #include "third_party/skia/include/core/SkBitmap.h"
49 #include "third_party/skia/include/core/SkColor.h" 50 #include "third_party/skia/include/core/SkColor.h"
50 #include "ui/base/resource/resource_bundle.h" 51 #include "ui/base/resource/resource_bundle.h"
51 #include "v8/include/v8.h" 52 #include "v8/include/v8.h"
52 #include "webkit/glue/webkit_glue.h" 53 #include "webkit/glue/webkit_glue.h"
53 54
55 using content::V8ValueConverter;
56 using extensions::ExtensionAPI;
54 using WebKit::WebFrame; 57 using WebKit::WebFrame;
55 using WebKit::WebView; 58 using WebKit::WebView;
56 59
57 namespace { 60 namespace {
58 61
59 const char* kExtensionDeps[] = { 62 const char* kExtensionDeps[] = {
60 "extensions/event.js", 63 "extensions/event.js",
61 "extensions/json_schema.js", 64 "extensions/json_schema.js",
62 "extensions/renderer_extension_bindings.js", 65 "extensions/miscellaneous_bindings.js",
63 "extensions/apitest.js" 66 "extensions/apitest.js"
64 }; 67 };
65 68
66 // Contains info relevant to a pending API request. 69 // Contains info relevant to a pending API request.
67 struct PendingRequest { 70 struct PendingRequest {
68 public : 71 public :
69 PendingRequest(v8::Persistent<v8::Context> context, const std::string& name, 72 PendingRequest(v8::Persistent<v8::Context> context, const std::string& name,
70 const std::string& extension_id) 73 const std::string& extension_id)
71 : context(context), name(name), extension_id(extension_id) { 74 : context(context), name(name), extension_id(extension_id) {
72 } 75 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 std::string extension_id_; 157 std::string extension_id_;
155 int browser_window_id_; 158 int browser_window_id_;
156 content::ViewType view_type_; 159 content::ViewType view_type_;
157 v8::Local<v8::Array> views_; 160 v8::Local<v8::Array> views_;
158 int index_; 161 int index_;
159 }; 162 };
160 163
161 class ExtensionImpl : public ChromeV8Extension { 164 class ExtensionImpl : public ChromeV8Extension {
162 public: 165 public:
163 explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher) 166 explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher)
164 : ChromeV8Extension("extensions/extension_process_bindings.js", 167 : ChromeV8Extension("extensions/schema_generated_bindings.js",
165 IDR_EXTENSION_PROCESS_BINDINGS_JS, 168 IDR_SCHEMA_GENERATED_BINDINGS_JS,
166 arraysize(kExtensionDeps), 169 arraysize(kExtensionDeps),
167 kExtensionDeps, 170 kExtensionDeps,
168 extension_dispatcher) { 171 extension_dispatcher) {
169 } 172 }
170 ~ExtensionImpl() {} 173
174 ~ExtensionImpl() {
175 // TODO(aa): It seems that v8 never deletes us, so this doesn't get called.
176 // Leaving this in here in case v8's implementation ever changes.
177 if (!extension_api_.IsEmpty())
178 extension_api_.Dispose();
179 }
171 180
172 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( 181 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
173 v8::Handle<v8::String> name) { 182 v8::Handle<v8::String> name) OVERRIDE {
174 if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) { 183 if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) {
175 return v8::FunctionTemplate::New(GetExtensionAPIDefinition); 184 return v8::FunctionTemplate::New(GetExtensionAPIDefinition,
185 v8::External::New(this));
176 } else if (name->Equals(v8::String::New("GetExtensionViews"))) { 186 } else if (name->Equals(v8::String::New("GetExtensionViews"))) {
177 return v8::FunctionTemplate::New(GetExtensionViews, 187 return v8::FunctionTemplate::New(GetExtensionViews,
178 v8::External::New(this)); 188 v8::External::New(this));
179 } else if (name->Equals(v8::String::New("GetNextRequestId"))) { 189 } else if (name->Equals(v8::String::New("GetNextRequestId"))) {
180 return v8::FunctionTemplate::New(GetNextRequestId); 190 return v8::FunctionTemplate::New(GetNextRequestId);
181 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) { 191 } else if (name->Equals(v8::String::New("OpenChannelToTab"))) {
182 return v8::FunctionTemplate::New(OpenChannelToTab); 192 return v8::FunctionTemplate::New(OpenChannelToTab);
183 } else if (name->Equals(v8::String::New("GetNextContextMenuId"))) { 193 } else if (name->Equals(v8::String::New("GetNextContextMenuId"))) {
184 return v8::FunctionTemplate::New(GetNextContextMenuId); 194 return v8::FunctionTemplate::New(GetNextContextMenuId);
185 } else if (name->Equals(v8::String::New("GetNextTtsEventId"))) { 195 } else if (name->Equals(v8::String::New("GetNextTtsEventId"))) {
(...skipping 18 matching lines...) Expand all
204 } else if (name->Equals(v8::String::New("CreateBlob"))) { 214 } else if (name->Equals(v8::String::New("CreateBlob"))) {
205 return v8::FunctionTemplate::New(CreateBlob, v8::External::New(this)); 215 return v8::FunctionTemplate::New(CreateBlob, v8::External::New(this));
206 } 216 }
207 217
208 return ChromeV8Extension::GetNativeFunction(name); 218 return ChromeV8Extension::GetNativeFunction(name);
209 } 219 }
210 220
211 private: 221 private:
212 static v8::Handle<v8::Value> GetExtensionAPIDefinition( 222 static v8::Handle<v8::Value> GetExtensionAPIDefinition(
213 const v8::Arguments& args) { 223 const v8::Arguments& args) {
214 return v8::String::NewExternal( 224 ExtensionImpl* self = GetFromArguments<ExtensionImpl>(args);
215 new StaticV8ExternalAsciiStringResource( 225 if (!self->extension_api_.IsEmpty())
216 ResourceBundle::GetSharedInstance().GetRawDataResource( 226 return self->extension_api_;
217 IDR_EXTENSION_API_JSON))); 227
228 v8::Persistent<v8::Context> context(v8::Context::New());
229 v8::Context::Scope context_scope(context);
230
231 scoped_ptr<V8ValueConverter> v8_value_converter(V8ValueConverter::create());
232 self->extension_api_ = v8::Persistent<v8::Array>::New(
233 v8::Handle<v8::Array>::Cast(
234 v8_value_converter->ToV8Value(
235 ExtensionAPI::GetInstance()->value(), context)));
236 CHECK(!self->extension_api_.IsEmpty());
237
238 // The persistent extension_api_ will keep the context alive.
239 context.Dispose();
240
241 return self->extension_api_;
218 } 242 }
219 243
220 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) { 244 static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args) {
221 if (args.Length() != 2) 245 if (args.Length() != 2)
222 return v8::Undefined(); 246 return v8::Undefined();
223 247
224 if (!args[0]->IsInt32() || !args[1]->IsString()) 248 if (!args[0]->IsInt32() || !args[1]->IsString())
225 return v8::Undefined(); 249 return v8::Undefined();
226 250
227 // |browser_window_id| == extension_misc::kUnknownWindowId means getting 251 // |browser_window_id| == extension_misc::kUnknownWindowId means getting
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 return v8::Undefined(); 475 return v8::Undefined();
452 476
453 std::string name = *v8::String::AsciiValue(args[0]); 477 std::string name = *v8::String::AsciiValue(args[0]);
454 const std::set<std::string>& function_names = 478 const std::set<std::string>& function_names =
455 v8_extension->extension_dispatcher_->function_names(); 479 v8_extension->extension_dispatcher_->function_names();
456 if (function_names.find(name) == function_names.end()) { 480 if (function_names.find(name) == function_names.end()) {
457 NOTREACHED() << "Unexpected function " << name; 481 NOTREACHED() << "Unexpected function " << name;
458 return v8::Undefined(); 482 return v8::Undefined();
459 } 483 }
460 484
461 // TODO(aa): add this to ChromeV8Context. 485 if (!v8_extension->CheckCurrentContextAccessToExtensionAPI(name))
462 if (!v8_extension->CheckPermissionForCurrentRenderView(name))
463 return v8::Undefined(); 486 return v8::Undefined();
464 487
465 GURL source_url; 488 GURL source_url;
466 WebFrame* webframe = current_context->web_frame(); 489 WebFrame* webframe = current_context->web_frame();
467 if (webframe) 490 if (webframe)
468 source_url = webframe->document().url(); 491 source_url = webframe->document().url();
469 492
470 int request_id = args[2]->Int32Value(); 493 int request_id = args[2]->Int32Value();
471 bool has_callback = args[3]->BooleanValue(); 494 bool has_callback = args[3]->BooleanValue();
472 bool for_io_thread = args[4]->BooleanValue(); 495 bool for_io_thread = args[4]->BooleanValue();
473 496
474 v8::Persistent<v8::Context> v8_context = 497 v8::Persistent<v8::Context> v8_context =
475 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); 498 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
476 DCHECK(!v8_context.IsEmpty()); 499 DCHECK(!v8_context.IsEmpty());
477 g_pending_requests.Get()[request_id].reset(new PendingRequest( 500 g_pending_requests.Get()[request_id].reset(new PendingRequest(
478 v8_context, name, current_context->extension_id())); 501 v8_context, name, current_context->extension_id()));
479 502
480 ExtensionHostMsg_Request_Params params; 503 ExtensionHostMsg_Request_Params params;
481 params.name = name; 504 params.name = name;
482 params.arguments.Swap(value_args); 505 params.arguments.Swap(value_args);
506 params.extension_id = current_context->extension_id();
483 params.source_url = source_url; 507 params.source_url = source_url;
484 params.request_id = request_id; 508 params.request_id = request_id;
485 params.has_callback = has_callback; 509 params.has_callback = has_callback;
486 params.user_gesture = 510 params.user_gesture =
487 webframe ? webframe->isProcessingUserGesture() : false; 511 webframe ? webframe->isProcessingUserGesture() : false;
488 if (for_io_thread) { 512 if (for_io_thread) {
489 renderview->Send(new ExtensionHostMsg_RequestForIOThread( 513 renderview->Send(new ExtensionHostMsg_RequestForIOThread(
490 renderview->GetRoutingId(), params)); 514 renderview->GetRoutingId(), params));
491 } else { 515 } else {
492 renderview->Send(new ExtensionHostMsg_Request( 516 renderview->Send(new ExtensionHostMsg_Request(
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 606
583 return StartRequestCommon(args, &list_value); 607 return StartRequestCommon(args, &list_value);
584 } 608 }
585 609
586 static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) { 610 static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) {
587 content::RenderView* renderview = GetCurrentRenderView(); 611 content::RenderView* renderview = GetCurrentRenderView();
588 if (!renderview) 612 if (!renderview)
589 return v8::Undefined(); 613 return v8::Undefined();
590 return v8::Integer::New(renderview->GetRoutingId()); 614 return v8::Integer::New(renderview->GetRoutingId());
591 } 615 }
616
617 // Cached JS Array representation of extension_api.json. We store this so that
618 // we don't have to parse it over and over again for every context that uses
619 // it.
620 v8::Persistent<v8::Array> extension_api_;
592 }; 621 };
593 622
594 } // namespace 623 } // namespace
595 624
596 v8::Extension* ExtensionProcessBindings::Get( 625 namespace extensions {
626
627 v8::Extension* SchemaGeneratedBindings::Get(
597 ExtensionDispatcher* extension_dispatcher) { 628 ExtensionDispatcher* extension_dispatcher) {
598 static v8::Extension* extension = new ExtensionImpl(extension_dispatcher); 629 static v8::Extension* extension = new ExtensionImpl(extension_dispatcher);
599 CHECK_EQ(extension_dispatcher, 630 CHECK_EQ(extension_dispatcher,
600 static_cast<ExtensionImpl*>(extension)->extension_dispatcher()); 631 static_cast<ExtensionImpl*>(extension)->extension_dispatcher());
601 return extension; 632 return extension;
602 } 633 }
603 634
604 // static 635 // static
605 void ExtensionProcessBindings::HandleResponse( 636 void SchemaGeneratedBindings::HandleResponse(const ChromeV8ContextSet& contexts,
606 const ChromeV8ContextSet& contexts, 637 int request_id,
607 int request_id, 638 bool success,
608 bool success, 639 const std::string& response,
609 const std::string& response, 640 const std::string& error,
610 const std::string& error, 641 std::string* extension_id) {
611 std::string* extension_id) {
612 PendingRequestMap::iterator request = 642 PendingRequestMap::iterator request =
613 g_pending_requests.Get().find(request_id); 643 g_pending_requests.Get().find(request_id);
614 if (request == g_pending_requests.Get().end()) { 644 if (request == g_pending_requests.Get().end()) {
615 // This should not be able to happen since we only remove requests when they 645 // This should not be able to happen since we only remove requests when they
616 // are handled. 646 // are handled.
617 LOG(ERROR) << "Could not find specified request id: " << request_id; 647 LOG(ERROR) << "Could not find specified request id: " << request_id;
618 return; 648 return;
619 } 649 }
620 650
621 ChromeV8Context* v8_context = 651 ChromeV8Context* v8_context =
(...skipping 25 matching lines...) Expand all
647 677
648 // Save the extension id before erasing the request. 678 // Save the extension id before erasing the request.
649 *extension_id = request->second->extension_id; 679 *extension_id = request->second->extension_id;
650 680
651 request->second->context.Dispose(); 681 request->second->context.Dispose();
652 request->second->context.Clear(); 682 request->second->context.Clear();
653 g_pending_requests.Get().erase(request); 683 g_pending_requests.Get().erase(request);
654 } 684 }
655 685
656 // static 686 // static
657 bool ExtensionProcessBindings::HasPendingRequests( 687 bool SchemaGeneratedBindings::HasPendingRequests(
658 const std::string& extension_id) { 688 const std::string& extension_id) {
659 for (PendingRequestMap::const_iterator it = g_pending_requests.Get().begin(); 689 for (PendingRequestMap::const_iterator it = g_pending_requests.Get().begin();
660 it != g_pending_requests.Get().end(); ++it) { 690 it != g_pending_requests.Get().end(); ++it) {
661 if (it->second->extension_id == extension_id) 691 if (it->second->extension_id == extension_id)
662 return true; 692 return true;
663 } 693 }
664 return false; 694 return false;
665 } 695 }
696
697 } // namespace
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/schema_generated_bindings.h ('k') | chrome/renderer/renderer_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698