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

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

Issue 9903010: Extract ExtensionRequestSender from SchemaGeneratedBindings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: respond to comments Created 8 years, 8 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/schema_generated_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 10
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/json/json_reader.h" 13 #include "base/json/json_reader.h"
14 #include "base/lazy_instance.h"
15 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
16 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
17 #include "base/string_util.h" 16 #include "base/string_util.h"
18 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/extensions/extension_action.h" 18 #include "chrome/common/extensions/extension_action.h"
20 #include "chrome/common/extensions/extension_constants.h" 19 #include "chrome/common/extensions/extension_constants.h"
21 #include "chrome/common/extensions/extension_messages.h" 20 #include "chrome/common/extensions/extension_messages.h"
22 #include "chrome/common/extensions/extension_set.h" 21 #include "chrome/common/extensions/extension_set.h"
23 #include "chrome/common/extensions/url_pattern.h" 22 #include "chrome/common/extensions/url_pattern.h"
24 #include "chrome/common/extensions/api/extension_api.h" 23 #include "chrome/common/extensions/api/extension_api.h"
25 #include "chrome/common/render_messages.h" 24 #include "chrome/common/render_messages.h"
26 #include "chrome/renderer/chrome_render_process_observer.h" 25 #include "chrome/renderer/chrome_render_process_observer.h"
27 #include "chrome/renderer/extensions/chrome_v8_context.h" 26 #include "chrome/renderer/extensions/chrome_v8_context.h"
28 #include "chrome/renderer/extensions/chrome_v8_context_set.h" 27 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
29 #include "chrome/renderer/extensions/event_bindings.h" 28 #include "chrome/renderer/extensions/event_bindings.h"
30 #include "chrome/renderer/extensions/extension_dispatcher.h" 29 #include "chrome/renderer/extensions/extension_dispatcher.h"
30 #include "chrome/renderer/extensions/extension_request_sender.h"
31 #include "chrome/renderer/extensions/miscellaneous_bindings.h" 31 #include "chrome/renderer/extensions/miscellaneous_bindings.h"
32 #include "chrome/renderer/extensions/user_script_slave.h" 32 #include "chrome/renderer/extensions/user_script_slave.h"
33 #include "content/public/renderer/render_thread.h" 33 #include "content/public/renderer/render_thread.h"
34 #include "content/public/renderer/render_view.h" 34 #include "content/public/renderer/render_view.h"
35 #include "content/public/renderer/v8_value_converter.h" 35 #include "content/public/renderer/v8_value_converter.h"
36 #include "grit/common_resources.h" 36 #include "grit/common_resources.h"
37 #include "grit/renderer_resources.h" 37 #include "grit/renderer_resources.h"
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
41 #include "third_party/skia/include/core/SkBitmap.h" 38 #include "third_party/skia/include/core/SkBitmap.h"
42 #include "third_party/skia/include/core/SkColor.h" 39 #include "third_party/skia/include/core/SkColor.h"
43 #include "ui/base/resource/resource_bundle.h" 40 #include "ui/base/resource/resource_bundle.h"
44 #include "v8/include/v8.h" 41 #include "v8/include/v8.h"
45 #include "webkit/glue/webkit_glue.h" 42 #include "webkit/glue/webkit_glue.h"
46 43
47 using content::RenderThread; 44 using content::RenderThread;
48 using content::V8ValueConverter; 45 using content::V8ValueConverter;
49 using extensions::ExtensionAPI; 46 using extensions::ExtensionAPI;
50 using extensions::Feature; 47 using extensions::Feature;
51 using WebKit::WebFrame; 48 using WebKit::WebFrame;
52 using WebKit::WebSecurityOrigin; 49 using WebKit::WebSecurityOrigin;
53 50
54 namespace {
55
56 // Contains info relevant to a pending API request.
57 struct PendingRequest {
58 public :
59 PendingRequest(v8::Persistent<v8::Context> context, const std::string& name,
60 const std::string& extension_id)
61 : context(context), name(name), extension_id(extension_id) {
62 }
63 v8::Persistent<v8::Context> context;
64 std::string name;
65 std::string extension_id;
66 };
67
68 class PendingRequestMap {
69 public:
70 PendingRequestMap() {
71 }
72
73 void InsertRequest(int request_id, PendingRequest* pending_request) {
74 pending_requests_[request_id].reset(pending_request);
75 }
76
77 PendingRequest* GetPendingRequest(int request_id) {
78 PendingRequests::iterator i = pending_requests_.find(request_id);
79 if (i == pending_requests_.end()) {
80 return NULL;
81 }
82 return i->second.get();
83 }
84
85 void RemoveRequest(int request_id) {
86 PendingRequest* request = GetPendingRequest(request_id);
87 if (!request)
88 return;
89 request->context.Dispose();
90 request->context.Clear();
91 pending_requests_.erase(request_id);
92 }
93
94 private:
95 typedef std::map<int, linked_ptr<PendingRequest> > PendingRequests;
96 PendingRequests pending_requests_;
97
98 DISALLOW_COPY_AND_ASSIGN(PendingRequestMap);
99 };
100
101 // TODO(koz): Make this owned by ExtensionDispatcher and pass it into
102 // SchemaGeneratedBindings.
103 base::LazyInstance<PendingRequestMap> g_pending_requests =
104 LAZY_INSTANCE_INITIALIZER;
105
106 } // namespace
107
108 namespace extensions { 51 namespace extensions {
109 52
110 SchemaGeneratedBindings::SchemaGeneratedBindings( 53 SchemaGeneratedBindings::SchemaGeneratedBindings(
111 ExtensionDispatcher* extension_dispatcher) 54 ExtensionDispatcher* extension_dispatcher,
112 : ChromeV8Extension(extension_dispatcher) { 55 ExtensionRequestSender* request_sender)
56 : ChromeV8Extension(extension_dispatcher),
57 request_sender_(request_sender) {
113 RouteFunction("GetExtensionAPIDefinition", 58 RouteFunction("GetExtensionAPIDefinition",
114 base::Bind(&SchemaGeneratedBindings::GetExtensionAPIDefinition, 59 base::Bind(&SchemaGeneratedBindings::GetExtensionAPIDefinition,
115 base::Unretained(this))); 60 base::Unretained(this)));
116 RouteFunction("GetNextRequestId", 61 RouteFunction("GetNextRequestId",
117 base::Bind(&SchemaGeneratedBindings::GetNextRequestId, 62 base::Bind(&SchemaGeneratedBindings::GetNextRequestId,
118 base::Unretained(this))); 63 base::Unretained(this)));
119 RouteFunction("StartRequest", 64 RouteFunction("StartRequest",
120 base::Bind(&SchemaGeneratedBindings::StartRequest, 65 base::Bind(&SchemaGeneratedBindings::StartRequest,
121 base::Unretained(this))); 66 base::Unretained(this)));
122 RouteFunction("SetIconCommon", 67 RouteFunction("SetIconCommon",
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 99 }
155 100
156 v8::Handle<v8::Value> SchemaGeneratedBindings::GetNextRequestId( 101 v8::Handle<v8::Value> SchemaGeneratedBindings::GetNextRequestId(
157 const v8::Arguments& args) { 102 const v8::Arguments& args) {
158 static int next_request_id = 0; 103 static int next_request_id = 0;
159 return v8::Integer::New(next_request_id++); 104 return v8::Integer::New(next_request_id++);
160 } 105 }
161 106
162 v8::Handle<v8::Value> SchemaGeneratedBindings::StartRequestCommon( 107 v8::Handle<v8::Value> SchemaGeneratedBindings::StartRequestCommon(
163 const v8::Arguments& args, ListValue* value_args) { 108 const v8::Arguments& args, ListValue* value_args) {
164
165 const ChromeV8ContextSet& contexts =
166 extension_dispatcher()->v8_context_set();
167 ChromeV8Context* current_context = contexts.GetCurrent();
168 if (!current_context)
169 return v8::Undefined();
170
171 // Get the current RenderView so that we can send a routed IPC message from
172 // the correct source.
173 content::RenderView* renderview = current_context->GetRenderView();
174 if (!renderview)
175 return v8::Undefined();
176
177 std::string name = *v8::String::AsciiValue(args[0]); 109 std::string name = *v8::String::AsciiValue(args[0]);
178 const std::set<std::string>& function_names =
179 extension_dispatcher_->function_names();
180 if (function_names.find(name) == function_names.end()) {
181 NOTREACHED() << "Unexpected function " << name <<
182 ". Did you remember to register it with ExtensionFunctionRegistry?";
183 return v8::Undefined();
184 }
185
186 if (!CheckCurrentContextAccessToExtensionAPI(name))
187 return v8::Undefined();
188
189 GURL source_url;
190 WebSecurityOrigin source_origin;
191 WebFrame* webframe = current_context->web_frame();
192 if (webframe) {
193 source_url = webframe->document().url();
194 source_origin = webframe->document().securityOrigin();
195 }
196
197 int request_id = args[2]->Int32Value(); 110 int request_id = args[2]->Int32Value();
198 bool has_callback = args[3]->BooleanValue(); 111 bool has_callback = args[3]->BooleanValue();
199 bool for_io_thread = args[4]->BooleanValue(); 112 bool for_io_thread = args[4]->BooleanValue();
200 113
201 v8::Persistent<v8::Context> v8_context = 114 request_sender_->StartRequest(name,
202 v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); 115 request_id,
203 DCHECK(!v8_context.IsEmpty()); 116 has_callback,
204 g_pending_requests.Get().InsertRequest(request_id, new PendingRequest( 117 for_io_thread,
205 v8_context, name, current_context->extension_id())); 118 value_args);
206
207 ExtensionHostMsg_Request_Params params;
208 params.name = name;
209 params.arguments.Swap(value_args);
210 params.extension_id = current_context->extension_id();
211 params.source_url = source_url;
212 params.source_origin = source_origin.toString();
213 params.request_id = request_id;
214 params.has_callback = has_callback;
215 params.user_gesture =
216 webframe ? webframe->isProcessingUserGesture() : false;
217 if (for_io_thread) {
218 renderview->Send(new ExtensionHostMsg_RequestForIOThread(
219 renderview->GetRoutingID(), params));
220 } else {
221 renderview->Send(new ExtensionHostMsg_Request(
222 renderview->GetRoutingID(), params));
223 }
224
225 return v8::Undefined(); 119 return v8::Undefined();
226 } 120 }
227 121
228 // Starts an API request to the browser, with an optional callback. The 122 // Starts an API request to the browser, with an optional callback. The
229 // callback will be dispatched to EventBindings::HandleResponse. 123 // callback will be dispatched to EventBindings::HandleResponse.
230 v8::Handle<v8::Value> SchemaGeneratedBindings::StartRequest( 124 v8::Handle<v8::Value> SchemaGeneratedBindings::StartRequest(
231 const v8::Arguments& args) { 125 const v8::Arguments& args) {
232 std::string str_args = *v8::String::Utf8Value(args[1]); 126 std::string str_args = *v8::String::Utf8Value(args[1]);
233 base::JSONReader reader; 127 base::JSONReader reader;
234 scoped_ptr<Value> value_args; 128 scoped_ptr<Value> value_args;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 dict->SetInteger("tabId", 197 dict->SetInteger("tabId",
304 details->Get(v8::String::New("tabId"))->Int32Value()); 198 details->Get(v8::String::New("tabId"))->Int32Value());
305 } 199 }
306 200
307 ListValue list_value; 201 ListValue list_value;
308 list_value.Append(dict); 202 list_value.Append(dict);
309 203
310 return StartRequestCommon(args, &list_value); 204 return StartRequestCommon(args, &list_value);
311 } 205 }
312 206
313 // static
314 void SchemaGeneratedBindings::HandleResponse(const ChromeV8ContextSet& contexts,
315 int request_id,
316 bool success,
317 const std::string& response,
318 const std::string& error,
319 std::string* extension_id) {
320 PendingRequest* request =
321 g_pending_requests.Get().GetPendingRequest(request_id);
322 if (!request) {
323 // This should not be able to happen since we only remove requests when they
324 // are handled.
325 LOG(ERROR) << "Could not find specified request id: " << request_id;
326 return;
327 }
328
329 ChromeV8Context* v8_context =
330 contexts.GetByV8Context(request->context);
331 if (!v8_context)
332 return; // The frame went away.
333
334 v8::HandleScope handle_scope;
335 v8::Handle<v8::Value> argv[5];
336 argv[0] = v8::Integer::New(request_id);
337 argv[1] = v8::String::New(request->name.c_str());
338 argv[2] = v8::Boolean::New(success);
339 argv[3] = v8::String::New(response.c_str());
340 argv[4] = v8::String::New(error.c_str());
341
342 v8::Handle<v8::Value> retval;
343 CHECK(v8_context->CallChromeHiddenMethod("handleResponse",
344 arraysize(argv),
345 argv,
346 &retval));
347 // In debug, the js will validate the callback parameters and return a
348 // string if a validation error has occured.
349 #ifndef NDEBUG
350 if (!retval.IsEmpty() && !retval->IsUndefined()) {
351 std::string error = *v8::String::AsciiValue(retval);
352 DCHECK(false) << error;
353 }
354 #endif
355
356 // Save the extension id before erasing the request.
357 *extension_id = request->extension_id;
358
359 g_pending_requests.Get().RemoveRequest(request_id);
360 }
361
362 } // namespace extensions 207 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698