| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ |
| #define EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "extensions/renderer/bindings/api_binding_types.h" |
| #include "v8/include/v8.h" |
| |
| namespace gin { |
| class Arguments; |
| } // namespace gin |
| |
| namespace extensions { |
| class APIBindingHooksDelegate; |
| class APITypeReferenceMap; |
| class APISignature; |
| class APIRequestHandler; |
| |
| // A class to register custom hooks for given API calls that need different |
| // handling. An instance exists for a single API, but can be used across |
| // multiple contexts (but only on the same thread). |
| // TODO(devlin): We have both C++ and JS custom bindings, but this only allows |
| // for registration of C++ handlers. Add JS support. |
| class APIBindingHooks { |
| public: |
| // The result of checking for hooks to handle a request. |
| struct RequestResult { |
| enum ResultCode { |
| HANDLED, // A custom hook handled the request. |
| ARGUMENTS_UPDATED, // The arguments were updated post-validation. |
| THROWN, // An exception was thrown during parsing or |
| // handling. |
| INVALID_INVOCATION, // The request was called with invalid arguments. |
| // `error` will contain the invocation error. |
| CONTEXT_INVALIDATED, // The context was invalidated during the handling |
| // of the API. Ideally, this wouldn't happen, but |
| // could in certain circumstances. |
| NOT_HANDLED, // The request was not handled. |
| }; |
| |
| explicit RequestResult(ResultCode code); |
| RequestResult(ResultCode code, v8::Local<v8::Function> custom_callback); |
| RequestResult(ResultCode code, |
| v8::Local<v8::Function> custom_callback, |
| binding::ResultModifierFunction result_modifier); |
| explicit RequestResult(std::string invocation_error); |
| RequestResult(RequestResult&& other); |
| ~RequestResult(); |
| |
| ResultCode code; |
| v8::Local<v8::Function> custom_callback; |
| binding::ResultModifierFunction result_modifier; |
| v8::Local<v8::Value> return_value; // Only valid if code == HANDLED. |
| std::string error; |
| }; |
| |
| APIBindingHooks(const std::string& api_name, |
| APIRequestHandler* request_handler); |
| |
| APIBindingHooks(const APIBindingHooks&) = delete; |
| APIBindingHooks& operator=(const APIBindingHooks&) = delete; |
| |
| ~APIBindingHooks(); |
| |
| // Looks for any custom hooks associated with the given request, and, if any |
| // are found, runs them. Returns the result of running the hooks, if any. |
| RequestResult RunHooks(const std::string& method_name, |
| v8::Local<v8::Context> context, |
| const APISignature* signature, |
| v8::LocalVector<v8::Value>* arguments, |
| const APITypeReferenceMap& type_refs); |
| |
| // Handler function to resolve asynchronous requests associated with handle |
| // request hooks. |
| void CompleteHandleRequest(int request_id, |
| bool did_succeed, |
| gin::Arguments* arguments); |
| |
| // Returns a JS interface that can be used to register hooks. |
| v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context); |
| |
| // Creates a new JS event for the given `event_name`, if a custom event is |
| // provided. Returns true if an event was created. |
| bool CreateCustomEvent(v8::Local<v8::Context> context, |
| const std::string& event_name, |
| v8::Local<v8::Value>* event_out); |
| |
| // Performs any extra initialization on the template. |
| void InitializeTemplate(v8::Isolate* isolate, |
| v8::Local<v8::ObjectTemplate> object_template, |
| const APITypeReferenceMap& type_refs); |
| |
| // Performs any extra initialization on an instance of the API. |
| void InitializeInstance(v8::Local<v8::Context> context, |
| v8::Local<v8::Object> instance); |
| |
| void SetDelegate(std::unique_ptr<APIBindingHooksDelegate> delegate); |
| |
| private: |
| // Updates the `arguments` by running `function` and settings arguments to the |
| // returned result. |
| bool UpdateArguments(v8::Local<v8::Function> function, |
| v8::Local<v8::Context> context, |
| v8::LocalVector<v8::Value>* arguments); |
| |
| // The name of the associated API. |
| std::string api_name_; |
| |
| // The request handler used to resolve asynchronous responses associated with |
| // handle request hooks. Guaranteed to outlive this object. |
| const raw_ptr<APIRequestHandler, DanglingUntriaged> request_handler_; |
| |
| std::unique_ptr<APIBindingHooksDelegate> delegate_; |
| |
| base::WeakPtrFactory<APIBindingHooks> weak_factory_{this}; |
| }; |
| |
| } // namespace extensions |
| |
| #endif // EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_ |