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

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

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