event_emitter.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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_EVENT_EMITTER_H_
  5. #define EXTENSIONS_RENDERER_BINDINGS_EVENT_EMITTER_H_
  6. #include <map>
  7. #include <vector>
  8. #include "extensions/common/mojom/event_dispatcher.mojom-forward.h"
  9. #include "extensions/renderer/bindings/js_runner.h"
  10. #include "gin/wrappable.h"
  11. #include "v8/include/v8.h"
  12. namespace gin {
  13. class Arguments;
  14. }
  15. namespace extensions {
  16. class APIEventListeners;
  17. class ExceptionHandler;
  18. // A gin::Wrappable Event object. One is expected to be created per event, per
  19. // context. Note: this object *does not* clear any events, so it must be
  20. // destroyed with the context to avoid leaking.
  21. class EventEmitter final : public gin::Wrappable<EventEmitter> {
  22. public:
  23. EventEmitter(bool supports_filters,
  24. std::unique_ptr<APIEventListeners> listeners,
  25. ExceptionHandler* exception_handler);
  26. EventEmitter(const EventEmitter&) = delete;
  27. EventEmitter& operator=(const EventEmitter&) = delete;
  28. ~EventEmitter() override;
  29. static gin::WrapperInfo kWrapperInfo;
  30. // gin::Wrappable:
  31. gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
  32. v8::Isolate* isolate) final;
  33. const char* GetTypeName() final;
  34. // Fires the event to any listeners.
  35. // Warning: This can run arbitrary JS code, so the |context| may be
  36. // invalidated after this!
  37. void Fire(v8::Local<v8::Context> context,
  38. std::vector<v8::Local<v8::Value>>* args,
  39. mojom::EventFilteringInfoPtr filter,
  40. JSRunner::ResultCallback callback);
  41. // Fires the event to any listeners synchronously, and returns the result.
  42. // This should only be used if the caller is certain that JS is already
  43. // running (i.e., is not blocked).
  44. // Warning: This can run arbitrary JS code, so the |context| may be
  45. // invalidated after this!
  46. v8::Local<v8::Value> FireSync(v8::Local<v8::Context> context,
  47. std::vector<v8::Local<v8::Value>>* args,
  48. mojom::EventFilteringInfoPtr filter);
  49. // Removes all listeners and marks this object as invalid so that no more
  50. // are added.
  51. void Invalidate(v8::Local<v8::Context> context);
  52. // TODO(devlin): Consider making this a test-only method and exposing
  53. // HasListeners() instead.
  54. size_t GetNumListeners() const;
  55. private:
  56. // Bound methods for the Event JS object.
  57. void AddListener(gin::Arguments* arguments);
  58. void RemoveListener(gin::Arguments* arguments);
  59. bool HasListener(v8::Local<v8::Function> function);
  60. bool HasListeners();
  61. void Dispatch(gin::Arguments* arguments);
  62. // Dispatches an event synchronously to listeners, returning the result.
  63. v8::Local<v8::Value> DispatchSync(v8::Local<v8::Context> context,
  64. std::vector<v8::Local<v8::Value>>* args,
  65. mojom::EventFilteringInfoPtr filter);
  66. // Dispatches an event asynchronously to listeners.
  67. void DispatchAsync(v8::Local<v8::Context> context,
  68. std::vector<v8::Local<v8::Value>>* args,
  69. mojom::EventFilteringInfoPtr filter,
  70. JSRunner::ResultCallback callback);
  71. static void DispatchAsyncHelper(
  72. const v8::FunctionCallbackInfo<v8::Value>& info);
  73. // Whether or not this object is still valid; false upon context release.
  74. // When invalid, no listeners can be added or removed.
  75. bool valid_ = true;
  76. // Whether the event supports filters.
  77. bool supports_filters_ = false;
  78. std::unique_ptr<APIEventListeners> listeners_;
  79. // The associated exception handler; guaranteed to outlive this object.
  80. ExceptionHandler* const exception_handler_ = nullptr;
  81. // The next id to use in the pending_filters_ map.
  82. int next_filter_id_ = 0;
  83. // A constant to indicate an invalid id.
  84. static constexpr int kInvalidFilterId = -1;
  85. // The map of EventFilteringInfos for events that are pending dispatch (since
  86. // JS is suspended).
  87. std::map<int, mojom::EventFilteringInfoPtr> pending_filters_;
  88. };
  89. } // namespace extensions
  90. #endif // EXTENSIONS_RENDERER_BINDINGS_EVENT_EMITTER_H_