gin_port.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2017 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_GIN_PORT_H_
  5. #define EXTENSIONS_RENDERER_GIN_PORT_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/memory/weak_ptr.h"
  9. #include "extensions/common/api/messaging/port_id.h"
  10. #include "extensions/renderer/bindings/api_binding_util.h"
  11. #include "gin/wrappable.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "v8/include/v8-forward.h"
  14. namespace gin {
  15. class Arguments;
  16. }
  17. namespace extensions {
  18. class APIEventHandler;
  19. struct Message;
  20. // A gin::Wrappable implementation of runtime.Port exposed to extensions. This
  21. // provides a means for extensions to communicate with themselves and each
  22. // other. This message-passing usually involves IPCs to the browser; we delegate
  23. // out this responsibility. This class only handles the JS interface (both calls
  24. // from JS and forward events to JS).
  25. class GinPort final : public gin::Wrappable<GinPort> {
  26. public:
  27. class Delegate {
  28. public:
  29. virtual ~Delegate() {}
  30. // Posts a message to the port.
  31. virtual void PostMessageToPort(v8::Local<v8::Context> context,
  32. const PortId& port_id,
  33. int routing_id,
  34. std::unique_ptr<Message> message) = 0;
  35. // Closes the port.
  36. virtual void ClosePort(v8::Local<v8::Context> context,
  37. const PortId& port_id,
  38. int routing_id) = 0;
  39. };
  40. GinPort(v8::Local<v8::Context> context,
  41. const PortId& port_id,
  42. int routing_id,
  43. const std::string& name,
  44. APIEventHandler* event_handler,
  45. Delegate* delegate);
  46. GinPort(const GinPort&) = delete;
  47. GinPort& operator=(const GinPort&) = delete;
  48. ~GinPort() override;
  49. static gin::WrapperInfo kWrapperInfo;
  50. // gin::Wrappable:
  51. gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
  52. v8::Isolate* isolate) override;
  53. const char* GetTypeName() override;
  54. // Dispatches an event to any listeners of the onMessage event.
  55. void DispatchOnMessage(v8::Local<v8::Context> context,
  56. const Message& message);
  57. // Dispatches an event to any listeners of the onDisconnect event and closes
  58. // the port.
  59. void DispatchOnDisconnect(v8::Local<v8::Context> context);
  60. // Sets the |sender| property on the port. Note: this can only be called
  61. // before the `sender` property is accessed on the JS object, since it is
  62. // lazily set as a data property in first access.
  63. void SetSender(v8::Local<v8::Context> context, v8::Local<v8::Value> sender);
  64. const PortId& port_id() const { return port_id_; }
  65. int routing_id() const { return routing_id_; }
  66. const std::string& name() const { return name_; }
  67. bool is_closed_for_testing() const { return state_ == kDisconnected; }
  68. private:
  69. enum State {
  70. kActive, // The port is currently active.
  71. kDisconnected, // The port was disconnected by calling port.disconnect().
  72. kInvalidated, // The associated v8::Context has been invalidated.
  73. };
  74. // Handlers for the gin::Wrappable.
  75. // Port.disconnect()
  76. void DisconnectHandler(gin::Arguments* arguments);
  77. // Port.postMessage()
  78. void PostMessageHandler(gin::Arguments* arguments,
  79. v8::Local<v8::Value> v8_message);
  80. // Port.name
  81. std::string GetName();
  82. // Port.onDisconnect
  83. v8::Local<v8::Value> GetOnDisconnectEvent(gin::Arguments* arguments);
  84. // Port.onMessage
  85. v8::Local<v8::Value> GetOnMessageEvent(gin::Arguments* arguments);
  86. // Port.sender
  87. v8::Local<v8::Value> GetSender(gin::Arguments* arguments);
  88. // Helper method to return the event with the given |name| (either
  89. // onDisconnect or onMessage).
  90. v8::Local<v8::Object> GetEvent(v8::Local<v8::Context> context,
  91. base::StringPiece event_name);
  92. // Helper method to dispatch an event.
  93. void DispatchEvent(v8::Local<v8::Context> context,
  94. std::vector<v8::Local<v8::Value>>* args,
  95. base::StringPiece event_name);
  96. // Invalidates the port (due to the context being removed). Any further calls
  97. // to postMessage() or instantiating new events will fail.
  98. void OnContextInvalidated();
  99. // Invalidates the port's events after the port has been disconnected.
  100. void InvalidateEvents(v8::Local<v8::Context> context);
  101. // Throws the given |error|.
  102. void ThrowError(v8::Isolate* isolate, base::StringPiece error);
  103. // The current state of the port.
  104. State state_ = kActive;
  105. // The associated port id.
  106. const PortId port_id_;
  107. // The routing id associated with the port's context's render frame.
  108. // TODO(devlin/lazyboy): This won't work with service workers.
  109. const int routing_id_;
  110. // The port's name.
  111. const std::string name_;
  112. // The associated APIEventHandler. Guaranteed to outlive this object.
  113. APIEventHandler* const event_handler_;
  114. // The delegate for handling the message passing between ports. Guaranteed to
  115. // outlive this object.
  116. Delegate* const delegate_;
  117. // Whether the `sender` property has been accessed, and thus set on the
  118. // port JS object.
  119. bool accessed_sender_;
  120. // A listener for context invalidation. Note: this isn't actually optional;
  121. // it just needs to be created after |weak_factory_|, which needs to be the
  122. // final member.
  123. absl::optional<binding::ContextInvalidationListener>
  124. context_invalidation_listener_;
  125. base::WeakPtrFactory<GinPort> weak_factory_{this};
  126. };
  127. } // namespace extensions
  128. #endif // EXTENSIONS_RENDERER_GIN_PORT_H_