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

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

Issue 11571014: Lazy load chrome.* APIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: android compilation 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/request_sender.h" 5 #include "chrome/renderer/extensions/request_sender.h"
6 6
7 #include "base/values.h" 7 #include "base/values.h"
8 #include "chrome/common/extensions/extension_messages.h" 8 #include "chrome/common/extensions/extension_messages.h"
9 #include "chrome/renderer/extensions/chrome_v8_context.h" 9 #include "chrome/renderer/extensions/chrome_v8_context.h"
10 #include "chrome/renderer/extensions/chrome_v8_context_set.h"
11 #include "chrome/renderer/extensions/dispatcher.h" 10 #include "chrome/renderer/extensions/dispatcher.h"
12 #include "chrome/renderer/extensions/scoped_persistent.h" 11 #include "chrome/renderer/extensions/scoped_persistent.h"
13 #include "content/public/renderer/render_view.h" 12 #include "content/public/renderer/render_view.h"
14 #include "content/public/renderer/v8_value_converter.h" 13 #include "content/public/renderer/v8_value_converter.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebUserGestureIndicat or.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebUserGestureIndicat or.h"
19 18
20 using content::V8ValueConverter; 19 using content::V8ValueConverter;
21 20
22 namespace extensions { 21 namespace extensions {
23 22
24 // Contains info relevant to a pending API request. 23 // Contains info relevant to a pending API request.
25 struct PendingRequest { 24 struct PendingRequest {
26 public : 25 public :
27 PendingRequest(v8::Handle<v8::Context> context, 26 PendingRequest(const std::string& name, ChromeV8Context* context)
28 const std::string& name, 27 : name(name), context(context) {
29 const std::string& extension_id)
30 : context(context), name(name), extension_id(extension_id) {
31 } 28 }
32 29
33 ScopedPersistent<v8::Context> context;
34 std::string name; 30 std::string name;
35 std::string extension_id; 31 ChromeV8Context* context;
36 }; 32 };
37 33
38 RequestSender::RequestSender(Dispatcher* dispatcher, 34 RequestSender::RequestSender(Dispatcher* dispatcher) : dispatcher_(dispatcher) {
39 ChromeV8ContextSet* context_set)
40 : dispatcher_(dispatcher), context_set_(context_set) {
41 } 35 }
42 36
43 RequestSender::~RequestSender() { 37 RequestSender::~RequestSender() {
44 } 38 }
45 39
46 void RequestSender::InsertRequest(int request_id, 40 void RequestSender::InsertRequest(int request_id,
47 PendingRequest* pending_request) { 41 PendingRequest* pending_request) {
48 DCHECK_EQ(0u, pending_requests_.count(request_id)); 42 DCHECK_EQ(0u, pending_requests_.count(request_id));
49 pending_requests_[request_id].reset(pending_request); 43 pending_requests_[request_id].reset(pending_request);
50 } 44 }
51 45
52 linked_ptr<PendingRequest> RequestSender::RemoveRequest(int request_id) { 46 linked_ptr<PendingRequest> RequestSender::RemoveRequest(int request_id) {
53 PendingRequestMap::iterator i = pending_requests_.find(request_id); 47 PendingRequestMap::iterator i = pending_requests_.find(request_id);
54 if (i == pending_requests_.end()) 48 if (i == pending_requests_.end())
55 return linked_ptr<PendingRequest>(); 49 return linked_ptr<PendingRequest>();
56 linked_ptr<PendingRequest> result = i->second; 50 linked_ptr<PendingRequest> result = i->second;
57 pending_requests_.erase(i); 51 pending_requests_.erase(i);
58 return result; 52 return result;
59 } 53 }
60 54
61 void RequestSender::StartRequest(const std::string& name, 55 void RequestSender::StartRequest(ChromeV8Context* context,
56 const std::string& name,
62 int request_id, 57 int request_id,
63 bool has_callback, 58 bool has_callback,
64 bool for_io_thread, 59 bool for_io_thread,
65 base::ListValue* value_args) { 60 base::ListValue* value_args) {
66 ChromeV8Context* current_context = context_set_->GetCurrent();
67 if (!current_context)
68 return;
69
70 // Get the current RenderView so that we can send a routed IPC message from 61 // Get the current RenderView so that we can send a routed IPC message from
71 // the correct source. 62 // the correct source.
72 content::RenderView* renderview = current_context->GetRenderView(); 63 content::RenderView* renderview = context->GetRenderView();
73 if (!renderview) 64 if (!renderview)
74 return; 65 return;
75 66
76 const std::set<std::string>& function_names = dispatcher_->function_names(); 67 const std::set<std::string>& function_names = dispatcher_->function_names();
77 if (function_names.find(name) == function_names.end()) { 68 if (function_names.find(name) == function_names.end()) {
78 NOTREACHED() << "Unexpected function " << name << 69 NOTREACHED() << "Unexpected function " << name <<
79 ". Did you remember to register it with ExtensionFunctionRegistry?"; 70 ". Did you remember to register it with ExtensionFunctionRegistry?";
80 return; 71 return;
81 } 72 }
82 73
83 // TODO(koz): See if we can make this a CHECK. 74 // TODO(koz): See if we can make this a CHECK.
84 if (!dispatcher_->CheckCurrentContextAccessToExtensionAPI(name)) 75 if (!dispatcher_->CheckContextAccessToExtensionAPI(name, context))
85 return; 76 return;
86 77
87 GURL source_url; 78 GURL source_url;
88 WebKit::WebSecurityOrigin source_origin; 79 WebKit::WebSecurityOrigin source_origin;
89 WebKit::WebFrame* webframe = current_context->web_frame(); 80 WebKit::WebFrame* webframe = context->web_frame();
90 if (webframe) { 81 if (webframe) {
91 source_url = webframe->document().url(); 82 source_url = webframe->document().url();
92 source_origin = webframe->document().securityOrigin(); 83 source_origin = webframe->document().securityOrigin();
93 } 84 }
94 85
95 std::string extension_id = current_context->GetExtensionID(); 86 InsertRequest(request_id, new PendingRequest(name, context));
96 InsertRequest(request_id, new PendingRequest(
97 v8::Context::GetCurrent(), name, extension_id));
98 87
99 ExtensionHostMsg_Request_Params params; 88 ExtensionHostMsg_Request_Params params;
100 params.name = name; 89 params.name = name;
101 params.arguments.Swap(value_args); 90 params.arguments.Swap(value_args);
102 params.extension_id = extension_id; 91 params.extension_id = context->GetExtensionID();
103 params.source_url = source_url; 92 params.source_url = source_url;
104 params.source_origin = source_origin.toString(); 93 params.source_origin = source_origin.toString();
105 params.request_id = request_id; 94 params.request_id = request_id;
106 params.has_callback = has_callback; 95 params.has_callback = has_callback;
107 params.user_gesture = 96 params.user_gesture =
108 WebKit::WebUserGestureIndicator::isProcessingUserGesture(); 97 WebKit::WebUserGestureIndicator::isProcessingUserGesture();
109 if (for_io_thread) { 98 if (for_io_thread) {
110 renderview->Send(new ExtensionHostMsg_RequestForIOThread( 99 renderview->Send(new ExtensionHostMsg_RequestForIOThread(
111 renderview->GetRoutingID(), params)); 100 renderview->GetRoutingID(), params));
112 } else { 101 } else {
113 renderview->Send(new ExtensionHostMsg_Request( 102 renderview->Send(new ExtensionHostMsg_Request(
114 renderview->GetRoutingID(), params)); 103 renderview->GetRoutingID(), params));
115 } 104 }
116 } 105 }
117 106
118 void RequestSender::HandleResponse(int request_id, 107 void RequestSender::HandleResponse(int request_id,
119 bool success, 108 bool success,
120 const base::ListValue& responseList, 109 const base::ListValue& responseList,
121 const std::string& error) { 110 const std::string& error) {
122 linked_ptr<PendingRequest> request = RemoveRequest(request_id); 111 linked_ptr<PendingRequest> request = RemoveRequest(request_id);
123 112
124 if (!request.get()) { 113 if (!request.get()) {
125 // This should not be able to happen since we only remove requests when 114 // This can happen if a context is destroyed while a request is in flight.
126 // they are handled.
127 LOG(ERROR) << "Could not find specified request id: " << request_id;
128 return; 115 return;
129 } 116 }
130 117
131 ChromeV8Context* v8_context =
132 context_set_->GetByV8Context(request->context.get());
133 if (!v8_context)
134 return; // The frame went away.
135
136 v8::HandleScope handle_scope; 118 v8::HandleScope handle_scope;
137 119
138 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); 120 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
139 v8::Handle<v8::Value> argv[] = { 121 v8::Handle<v8::Value> argv[] = {
140 v8::Integer::New(request_id), 122 v8::Integer::New(request_id),
141 v8::String::New(request->name.c_str()), 123 v8::String::New(request->name.c_str()),
142 v8::Boolean::New(success), 124 v8::Boolean::New(success),
143 converter->ToV8Value(&responseList, v8_context->v8_context()), 125 converter->ToV8Value(&responseList, request->context->v8_context()),
144 v8::String::New(error.c_str()) 126 v8::String::New(error.c_str())
145 }; 127 };
146 128
147 v8::Handle<v8::Value> retval; 129 v8::Handle<v8::Value> retval;
148 CHECK(v8_context->CallChromeHiddenMethod("handleResponse", 130 CHECK(request->context->CallChromeHiddenMethod("handleResponse",
149 arraysize(argv), 131 arraysize(argv),
150 argv, 132 argv,
151 &retval)); 133 &retval));
152 // In debug, the js will validate the callback parameters and return a 134 // In debug, the js will validate the callback parameters and return a
153 // string if a validation error has occured. 135 // string if a validation error has occured.
154 if (DCHECK_IS_ON()) { 136 if (DCHECK_IS_ON()) {
155 if (!retval.IsEmpty() && !retval->IsUndefined()) { 137 if (!retval.IsEmpty() && !retval->IsUndefined()) {
156 std::string error = *v8::String::AsciiValue(retval); 138 std::string error = *v8::String::AsciiValue(retval);
157 DCHECK(false) << error; 139 DCHECK(false) << error;
158 } 140 }
159 } 141 }
160 } 142 }
161 143
144 void RequestSender::InvalidateContext(ChromeV8Context* context) {
145 for (PendingRequestMap::iterator it = pending_requests_.begin();
146 it != pending_requests_.end();) {
147 if (it->second->context == context)
148 pending_requests_.erase(it++);
149 else
150 ++it;
151 }
152 }
153
162 } // namespace extensions 154 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/request_sender.h ('k') | chrome/renderer/extensions/runtime_custom_bindings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698