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 3 // found in the LICENSE file. 4 5 #ifndef EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ 6 #define EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ 7 8 #include <memory> 9 #include <string> 10 11 #include "base/macros.h" 12 #include "v8/include/v8.h" 13 14 namespace extensions { 15 class APIBindingHooksDelegate; 16 class APITypeReferenceMap; 17 class APISignature; 18 19 // A class to register custom hooks for given API calls that need different 20 // handling. An instance exists for a single API, but can be used across 21 // multiple contexts (but only on the same thread). 22 // TODO(devlin): We have both C++ and JS custom bindings, but this only allows 23 // for registration of C++ handlers. Add JS support. 24 class APIBindingHooks { 25 public: 26 // The result of checking for hooks to handle a request. 27 struct RequestResult { 28 enum ResultCode { 29 HANDLED, // A custom hook handled the request. 30 ARGUMENTS_UPDATED, // The arguments were updated post-validation. 31 THROWN, // An exception was thrown during parsing or 32 // handling. 33 INVALID_INVOCATION, // The request was called with invalid arguments. 34 // |error| will contain the invocation error. 35 CONTEXT_INVALIDATED, // The context was invalidated during the handling 36 // of the API. Ideally, this wouldn't happen, but 37 // could in certain circumstances. 38 NOT_HANDLED, // The request was not handled. 39 }; 40 41 explicit RequestResult(ResultCode code); 42 RequestResult(ResultCode code, v8::Local<v8::Function> custom_callback); 43 RequestResult(std::string invocation_error); 44 RequestResult(const RequestResult& other); 45 ~RequestResult(); 46 47 ResultCode code; 48 v8::Local<v8::Function> custom_callback; 49 v8::Local<v8::Value> return_value; // Only valid if code == HANDLED. 50 std::string error; 51 }; 52 53 explicit APIBindingHooks(const std::string& api_name); 54 ~APIBindingHooks(); 55 56 // Looks for any custom hooks associated with the given request, and, if any 57 // are found, runs them. Returns the result of running the hooks, if any. 58 RequestResult RunHooks(const std::string& method_name, 59 v8::Local<v8::Context> context, 60 const APISignature* signature, 61 std::vector<v8::Local<v8::Value>>* arguments, 62 const APITypeReferenceMap& type_refs); 63 64 // Returns a JS interface that can be used to register hooks. 65 v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context); 66 67 // Gets the custom-set JS callback for the given method, if one exists. 68 v8::Local<v8::Function> GetCustomJSCallback(const std::string& method_name, 69 v8::Local<v8::Context> context); 70 71 // Creates a new JS event for the given |event_name|, if a custom event is 72 // provided. Returns true if an event was created. 73 bool CreateCustomEvent(v8::Local<v8::Context> context, 74 const std::string& event_name, 75 v8::Local<v8::Value>* event_out); 76 77 // Performs any extra initialization on the template. 78 void InitializeTemplate(v8::Isolate* isolate, 79 v8::Local<v8::ObjectTemplate> object_template, 80 const APITypeReferenceMap& type_refs); 81 82 // Performs any extra initialization on an instance of the API. 83 void InitializeInstance(v8::Local<v8::Context> context, 84 v8::Local<v8::Object> instance); 85 86 void SetDelegate(std::unique_ptr<APIBindingHooksDelegate> delegate); 87 88 private: 89 // Updates the |arguments| by running |function| and settings arguments to the 90 // returned result. 91 bool UpdateArguments(v8::Local<v8::Function> function, 92 v8::Local<v8::Context> context, 93 std::vector<v8::Local<v8::Value>>* arguments); 94 95 // The name of the associated API. 96 std::string api_name_; 97 98 std::unique_ptr<APIBindingHooksDelegate> delegate_; 99 100 DISALLOW_COPY_AND_ASSIGN(APIBindingHooks); 101 }; 102 103 } // namespace extensions 104 105 #endif // EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ 106