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

Side by Side Diff: extensions/renderer/api_request_handler.cc

Issue 2894923003: [Extensions Bindings] Include request id in a custom callback response (Closed)
Patch Set: really fix Created 3 years, 7 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "extensions/renderer/api_request_handler.h" 5 #include "extensions/renderer/api_request_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/guid.h" 8 #include "base/guid.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "content/public/child/v8_value_converter.h" 11 #include "content/public/child/v8_value_converter.h"
12 #include "gin/converter.h" 12 #include "gin/converter.h"
13 #include "gin/data_object_builder.h"
13 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" 14 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
14 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 15 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
15 16
16 namespace extensions { 17 namespace extensions {
17 18
18 APIRequestHandler::Request::Request() {} 19 APIRequestHandler::Request::Request() {}
19 APIRequestHandler::Request::~Request() = default; 20 APIRequestHandler::Request::~Request() = default;
20 21
21 APIRequestHandler::PendingRequest::PendingRequest( 22 APIRequestHandler::PendingRequest::PendingRequest(
22 v8::Isolate* isolate, 23 v8::Isolate* isolate,
(...skipping 27 matching lines...) Expand all
50 APIRequestHandler::~APIRequestHandler() {} 51 APIRequestHandler::~APIRequestHandler() {}
51 52
52 int APIRequestHandler::StartRequest(v8::Local<v8::Context> context, 53 int APIRequestHandler::StartRequest(v8::Local<v8::Context> context,
53 const std::string& method, 54 const std::string& method,
54 std::unique_ptr<base::ListValue> arguments, 55 std::unique_ptr<base::ListValue> arguments,
55 v8::Local<v8::Function> callback, 56 v8::Local<v8::Function> callback,
56 v8::Local<v8::Function> custom_callback, 57 v8::Local<v8::Function> custom_callback,
57 binding::RequestThread thread) { 58 binding::RequestThread thread) {
58 auto request = base::MakeUnique<Request>(); 59 auto request = base::MakeUnique<Request>();
59 60
61 // The request id is primarily used in the renderer to associate an API
62 // request with the associated callback, but it's also used in the browser as
63 // an identifier for the extension function (e.g. by the pageCapture API).
64 // TODO(devlin): We should probably fix this, since the request id is only
65 // unique per-isolate, rather than globally.
66 // TODO(devlin): We could *probably* get away with just using an integer
67 // here, but it's a little less foolproof. How slow is GenerateGUID? Should
68 // we use that instead? It means updating the IPC
69 // (ExtensionHostMsg_Request).
70 // base::UnguessableToken is another good option.
71 int request_id = next_request_id_++;
72 request->request_id = request_id;
73
60 if (!custom_callback.IsEmpty() || !callback.IsEmpty()) { 74 if (!custom_callback.IsEmpty() || !callback.IsEmpty()) {
61 v8::Isolate* isolate = context->GetIsolate(); 75 v8::Isolate* isolate = context->GetIsolate();
62 // In the JS bindings, custom callbacks are called with the arguments of 76 // In the JS bindings, custom callbacks are called with the arguments of
63 // name, the full request object (see below), the original callback, and 77 // name, the full request object (see below), the original callback, and
64 // the responses from the API. The responses from the API are handled by the 78 // the responses from the API. The responses from the API are handled by the
65 // APIRequestHandler, but we need to curry in the other values. 79 // APIRequestHandler, but we need to curry in the other values.
66 std::vector<v8::Local<v8::Value>> callback_args; 80 std::vector<v8::Local<v8::Value>> callback_args;
67 if (!custom_callback.IsEmpty()) { 81 if (!custom_callback.IsEmpty()) {
68 // TODO(devlin): The |request| object in the JS bindings includes 82 // TODO(devlin): The |request| object in the JS bindings includes
69 // properties for callback, callbackSchema, args, stack, id, and 83 // properties for callback, callbackSchema, args, stack, id, and
70 // customCallback. Of those, it appears that we only use stack, args, and 84 // customCallback. Of those, it appears that we only use stack, args, and
71 // id (since callback is curried in separately). We may be able to update 85 // id (since callback is curried in separately). We may be able to update
72 // bindings to get away from some of those. For now, just pass in an empty 86 // bindings to get away from some of those. For now, just pass in an
73 // object (most APIs don't rely on it). 87 // object with the request id.
74 v8::Local<v8::Object> request = v8::Object::New(isolate); 88 v8::Local<v8::Object> request =
89 gin::DataObjectBuilder(isolate).Set("id", request_id).Build();
75 v8::Local<v8::Value> callback_to_pass = callback; 90 v8::Local<v8::Value> callback_to_pass = callback;
76 if (callback_to_pass.IsEmpty()) 91 if (callback_to_pass.IsEmpty())
77 callback_to_pass = v8::Undefined(isolate); 92 callback_to_pass = v8::Undefined(isolate);
78 callback_args = {gin::StringToSymbol(isolate, method), request, 93 callback_args = {gin::StringToSymbol(isolate, method), request,
79 callback_to_pass}; 94 callback_to_pass};
80 callback = custom_callback; 95 callback = custom_callback;
81 } 96 }
82 97
83 // TODO(devlin): We could *probably* get away with just using an integer
84 // here, but it's a little less foolproof. How slow is GenerateGUID? Should
85 // we use that instead? It means updating the IPC
86 // (ExtensionHostMsg_Request).
87 // base::UnguessableToken is another good option.
88 request->request_id = next_request_id_++;
89 request->has_callback = true; 98 request->has_callback = true;
90 pending_requests_.insert(std::make_pair( 99 pending_requests_.insert(std::make_pair(
91 request->request_id, 100 request_id, PendingRequest(isolate, callback, context, callback_args)));
92 PendingRequest(isolate, callback, context, callback_args)));
93 } 101 }
94 102
95 request->has_user_gesture = 103 request->has_user_gesture =
96 blink::WebUserGestureIndicator::IsProcessingUserGestureThreadSafe(); 104 blink::WebUserGestureIndicator::IsProcessingUserGestureThreadSafe();
97 request->arguments = std::move(arguments); 105 request->arguments = std::move(arguments);
98 request->method_name = method; 106 request->method_name = method;
99 request->thread = thread; 107 request->thread = thread;
100 108
101 int id = request->request_id;
102 send_request_.Run(std::move(request), context); 109 send_request_.Run(std::move(request), context);
103 return id; 110 return request_id;
104 } 111 }
105 112
106 void APIRequestHandler::CompleteRequest(int request_id, 113 void APIRequestHandler::CompleteRequest(int request_id,
107 const base::ListValue& response_args, 114 const base::ListValue& response_args,
108 const std::string& error) { 115 const std::string& error) {
109 auto iter = pending_requests_.find(request_id); 116 auto iter = pending_requests_.find(request_id);
110 // The request may have been removed if the context was invalidated before a 117 // The request may have been removed if the context was invalidated before a
111 // response is ready. 118 // response is ready.
112 if (iter == pending_requests_.end()) 119 if (iter == pending_requests_.end())
113 return; 120 return;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 160 }
154 161
155 std::set<int> APIRequestHandler::GetPendingRequestIdsForTesting() const { 162 std::set<int> APIRequestHandler::GetPendingRequestIdsForTesting() const {
156 std::set<int> result; 163 std::set<int> result;
157 for (const auto& pair : pending_requests_) 164 for (const auto& pair : pending_requests_)
158 result.insert(pair.first); 165 result.insert(pair.first);
159 return result; 166 return result;
160 } 167 }
161 168
162 } // namespace extensions 169 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/api_bindings_system_unittest.cc ('k') | extensions/renderer/api_request_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698