1 // Copyright 2020 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 COMPONENTS_CAST_API_BINDINGS_SCOPED_API_BINDING_H_ 6 #define COMPONENTS_CAST_API_BINDINGS_SCOPED_API_BINDING_H_ 7 8 #include <memory> 9 10 #include "base/callback_forward.h" 11 #include "base/check.h" 12 #include "base/optional.h" 13 #include "base/strings/string_piece.h" 14 #include "components/cast/cast_component_export.h" 15 #include "components/cast/message_port/message_port.h" 16 17 namespace cast_api_bindings { 18 19 class Manager; 20 21 // Manages the registration of bindings Javascript and establishment of 22 // communication channels, as well as unregistration on object teardown, using 23 // RAII semantics. 24 class CAST_COMPONENT_EXPORT ScopedApiBinding 25 : public cast_api_bindings::MessagePort::Receiver { 26 public: 27 // Methods for handling message I/O with bindings scripts. 28 class Delegate { 29 public: 30 virtual ~Delegate() = default; 31 32 // Expresses the name for which MessagePort connection requests should be 33 // routed to the Delegate implementation. 34 virtual base::StringPiece GetPortName() const = 0; 35 36 // Invoked when |message_port_| is connected. This allows the Delegate to do 37 // work when the client first connects, e.g. sending it a message conveying 38 // some initial state. OnConnected()39 virtual void OnConnected() {} 40 41 // Invoked for messages received over |message_port_|. 42 virtual bool OnMessage(base::StringPiece message) = 0; 43 44 // Invoked when |message_port_| is disconnected. 45 // Allows the delegate to cleanup if the client unexpectedly disconnects. OnDisconnected()46 virtual void OnDisconnected() {} 47 }; 48 49 // |bindings_manager|: Specifies the Manager to which the binding will be 50 // published. 51 // |delegate|: If set, provides the necessary identifier and 52 // method implementations for connecting script message I/O with the 53 // bindings backend. 54 // Must outlive |this|. 55 // Can be nullptr if the bindings do not require communication. 56 // |js_bindings_id|: Id used for management of the |js_bindings| script. 57 // Must be unique. 58 // |js_bindings|: script to inject. 59 ScopedApiBinding(Manager* bindings_manager, 60 Delegate* delegate, 61 base::StringPiece js_bindings_id, 62 base::StringPiece js_bindings); 63 ~ScopedApiBinding() final; 64 65 ScopedApiBinding(const ScopedApiBinding&) = delete; 66 ScopedApiBinding& operator=(const ScopedApiBinding&) = delete; 67 68 // Sends a |message| to |message_port_|. 69 // Returns true if the message was sent. 70 bool SendMessage(base::StringPiece message); 71 72 private: 73 // Called when a port is received from the page. 74 void OnPortConnected(std::unique_ptr<cast_api_bindings::MessagePort> port); 75 76 // cast_api_bindings::MessagePort::Receiver implementation: 77 bool OnMessage( 78 base::StringPiece message, 79 std::vector<std::unique_ptr<cast_api_bindings::MessagePort>> ports) final; 80 void OnPipeError() final; 81 82 Manager* const bindings_manager_; 83 Delegate* const delegate_; 84 const std::string js_bindings_id_; 85 86 // The MessagePort used to receive messages from the receiver JS. 87 std::unique_ptr<cast_api_bindings::MessagePort> message_port_; 88 }; 89 90 } // namespace cast_api_bindings 91 92 #endif // COMPONENTS_CAST_API_BINDINGS_SCOPED_API_BINDING_H_ 93