api_binding_hooks.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. #ifndef EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_
  5. #define EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/memory/weak_ptr.h"
  9. #include "extensions/renderer/bindings/api_binding_types.h"
  10. #include "v8/include/v8.h"
  11. namespace gin {
  12. class Arguments;
  13. } // namespace gin
  14. namespace extensions {
  15. class APIBindingHooksDelegate;
  16. class APITypeReferenceMap;
  17. class APISignature;
  18. class APIRequestHandler;
  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. explicit RequestResult(ResultCode code);
  41. RequestResult(ResultCode code, v8::Local<v8::Function> custom_callback);
  42. RequestResult(ResultCode code,
  43. v8::Local<v8::Function> custom_callback,
  44. binding::ResultModifierFunction result_modifier);
  45. explicit RequestResult(std::string invocation_error);
  46. RequestResult(RequestResult&& other);
  47. ~RequestResult();
  48. ResultCode code;
  49. v8::Local<v8::Function> custom_callback;
  50. binding::ResultModifierFunction result_modifier;
  51. v8::Local<v8::Value> return_value; // Only valid if code == HANDLED.
  52. std::string error;
  53. };
  54. APIBindingHooks(const std::string& api_name,
  55. APIRequestHandler* request_handler);
  56. APIBindingHooks(const APIBindingHooks&) = delete;
  57. APIBindingHooks& operator=(const APIBindingHooks&) = delete;
  58. ~APIBindingHooks();
  59. // Looks for any custom hooks associated with the given request, and, if any
  60. // are found, runs them. Returns the result of running the hooks, if any.
  61. RequestResult RunHooks(const std::string& method_name,
  62. v8::Local<v8::Context> context,
  63. const APISignature* signature,
  64. std::vector<v8::Local<v8::Value>>* arguments,
  65. const APITypeReferenceMap& type_refs);
  66. // Handler function to resolve asynchronous requests associated with handle
  67. // request hooks.
  68. void CompleteHandleRequest(int request_id,
  69. bool did_succeed,
  70. gin::Arguments* arguments);
  71. // Returns a JS interface that can be used to register hooks.
  72. v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context);
  73. // Creates a new JS event for the given |event_name|, if a custom event is
  74. // provided. Returns true if an event was created.
  75. bool CreateCustomEvent(v8::Local<v8::Context> context,
  76. const std::string& event_name,
  77. v8::Local<v8::Value>* event_out);
  78. // Performs any extra initialization on the template.
  79. void InitializeTemplate(v8::Isolate* isolate,
  80. v8::Local<v8::ObjectTemplate> object_template,
  81. const APITypeReferenceMap& type_refs);
  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. void SetDelegate(std::unique_ptr<APIBindingHooksDelegate> delegate);
  86. private:
  87. // Updates the |arguments| by running |function| and settings arguments to the
  88. // returned result.
  89. bool UpdateArguments(v8::Local<v8::Function> function,
  90. v8::Local<v8::Context> context,
  91. std::vector<v8::Local<v8::Value>>* arguments);
  92. // The name of the associated API.
  93. std::string api_name_;
  94. // The request handler used to resolve asynchronous responses associated with
  95. // handle request hooks. Guaranteed to outlive this object.
  96. APIRequestHandler* const request_handler_;
  97. std::unique_ptr<APIBindingHooksDelegate> delegate_;
  98. base::WeakPtrFactory<APIBindingHooks> weak_factory_{this};
  99. };
  100. } // namespace extensions
  101. #endif // EXTENSIONS_RENDERER_BINDINGS_API_BINDING_HOOKS_H_