Chromium Code Reviews| Index: extensions/renderer/api_binding_hooks.cc | 
| diff --git a/extensions/renderer/api_binding_hooks.cc b/extensions/renderer/api_binding_hooks.cc | 
| index c4bc12c42ccd07ca1ad15c64c43003480d421830..79d8037b2ede9dd9e1fbb794ec7e4a7a5f17282c 100644 | 
| --- a/extensions/renderer/api_binding_hooks.cc | 
| +++ b/extensions/renderer/api_binding_hooks.cc | 
| @@ -33,12 +33,15 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { | 
| return Wrappable<JSHookInterface>::GetObjectTemplateBuilder(isolate) | 
| .SetMethod("setHandleRequest", &JSHookInterface::SetHandleRequest) | 
| .SetMethod("setUpdateArgumentsPreValidate", | 
| - &JSHookInterface::SetUpdateArgumentsPreValidate); | 
| + &JSHookInterface::SetUpdateArgumentsPreValidate) | 
| + .SetMethod("setUpdateArgumentsPostValidate", | 
| + &JSHookInterface::SetUpdateArgumentsPostValidate); | 
| } | 
| void ClearHooks() { | 
| handle_request_hooks_.clear(); | 
| pre_validation_hooks_.clear(); | 
| + post_validation_hooks_.clear(); | 
| } | 
| v8::Local<v8::Function> GetHandleRequestHook(const std::string& method_name, | 
| @@ -51,6 +54,11 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { | 
| return GetHookFromMap(pre_validation_hooks_, method_name, isolate); | 
| } | 
| + v8::Local<v8::Function> GetPostValidationHook(const std::string& method_name, | 
| + v8::Isolate* isolate) const { | 
| + return GetHookFromMap(post_validation_hooks_, method_name, isolate); | 
| + } | 
| + | 
| private: | 
| using JSHooks = std::map<std::string, v8::Global<v8::Function>>; | 
| @@ -92,10 +100,17 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { | 
| AddHookToMap(&pre_validation_hooks_, isolate, method_name, hook); | 
| } | 
| + void SetUpdateArgumentsPostValidate(v8::Isolate* isolate, | 
| + const std::string& method_name, | 
| + v8::Local<v8::Function> hook) { | 
| + AddHookToMap(&post_validation_hooks_, isolate, method_name, hook); | 
| + } | 
| + | 
| std::string api_name_; | 
| JSHooks handle_request_hooks_; | 
| JSHooks pre_validation_hooks_; | 
| + JSHooks post_validation_hooks_; | 
| DISALLOW_COPY_AND_ASSIGN(JSHookInterface); | 
| }; | 
| @@ -185,7 +200,7 @@ void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source, | 
| js_resource_name_ = std::move(resource_name); | 
| } | 
| -APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( | 
| +APIBindingHooks::RequestResult APIBindingHooks::RunHooks( | 
| const std::string& api_name, | 
| const std::string& method_name, | 
| v8::Local<v8::Context> context, | 
| @@ -232,9 +247,17 @@ APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( | 
| } | 
| } | 
| + v8::Local<v8::Function> post_validate_hook = | 
| + hook_interface->GetPostValidationHook(method_name, isolate); | 
| v8::Local<v8::Function> handle_request = | 
| hook_interface->GetHandleRequestHook(method_name, isolate); | 
| - if (!handle_request.IsEmpty()) { | 
| + // If both the post validation hook and the handle request hook are empty, | 
| + // we're done... | 
| + if (post_validate_hook.IsEmpty() && handle_request.IsEmpty()) | 
| + return RequestResult(RequestResult::NOT_HANDLED); | 
| + | 
| + { | 
| + // ... otherwise, we have to validate the arguments. | 
| v8::TryCatch try_catch(isolate); | 
| std::vector<v8::Local<v8::Value>> parsed_v8_args; | 
| std::string error; | 
| @@ -246,21 +269,33 @@ APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( | 
| } | 
| if (!success) | 
| return RequestResult(RequestResult::INVALID_INVOCATION); | 
| + arguments->swap(parsed_v8_args); | 
| + } | 
| - v8::Global<v8::Value> global_result = | 
| - run_js_.Run(handle_request, context, parsed_v8_args.size(), | 
| - parsed_v8_args.data()); | 
| + if (!post_validate_hook.IsEmpty()) { | 
| + v8::TryCatch try_catch(isolate); | 
| 
 
jbroman
2017/01/11 20:01:48
nit: A thought here: I don't see any place here wh
 
Devlin
2017/01/13 17:11:58
Done.
 
 | 
| + UpdateArguments(post_validate_hook, context, arguments); | 
| if (try_catch.HasCaught()) { | 
| try_catch.ReThrow(); | 
| return RequestResult(RequestResult::THROWN); | 
| } | 
| - RequestResult result(RequestResult::HANDLED); | 
| - if (!global_result.IsEmpty()) | 
| - result.return_value = global_result.Get(isolate); | 
| - return result; | 
| } | 
| - return RequestResult(RequestResult::NOT_HANDLED); | 
| + if (handle_request.IsEmpty()) | 
| + return RequestResult(RequestResult::NOT_HANDLED); | 
| + | 
| + v8::TryCatch try_catch(isolate); | 
| + v8::Global<v8::Value> global_result = | 
| + run_js_.Run(handle_request, context, arguments->size(), | 
| + arguments->data()); | 
| + if (try_catch.HasCaught()) { | 
| + try_catch.ReThrow(); | 
| + return RequestResult(RequestResult::THROWN); | 
| + } | 
| + RequestResult result(RequestResult::HANDLED); | 
| + if (!global_result.IsEmpty()) | 
| + result.return_value = global_result.Get(isolate); | 
| + return result; | 
| } | 
| void APIBindingHooks::InitializeInContext( |