xref: /aosp_15_r20/external/openscreen/cast/standalone_sender/looping_file_cast_agent.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
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 CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_
6 #define CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_
7 
8 #include <openssl/x509.h>
9 
10 #include <functional>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "absl/types/optional.h"
16 #include "cast/common/channel/cast_message_handler.h"
17 #include "cast/common/channel/cast_socket_message_port.h"
18 #include "cast/common/channel/connection_namespace_handler.h"
19 #include "cast/common/channel/virtual_connection_router.h"
20 #include "cast/common/public/cast_socket.h"
21 #include "cast/sender/public/sender_socket_factory.h"
22 #include "cast/standalone_sender/connection_settings.h"
23 #include "cast/standalone_sender/looping_file_sender.h"
24 #include "cast/standalone_sender/remoting_sender.h"
25 #include "cast/streaming/environment.h"
26 #include "cast/streaming/sender_session.h"
27 #include "platform/api/scoped_wake_lock.h"
28 #include "platform/api/serial_delete_ptr.h"
29 #include "platform/base/error.h"
30 #include "platform/base/interface_info.h"
31 #include "platform/impl/task_runner.h"
32 
33 namespace Json {
34 class Value;
35 }
36 
37 namespace openscreen {
38 namespace cast {
39 
40 // A single-use sender-side Cast Agent that manages the workflow for a mirroring
41 // session, casting the content from a local file indefinitely. After being
42 // constructed and having its Connect() method called, the LoopingFileCastAgent
43 // steps through the following workflow:
44 //
45 //   1. Waits for a CastSocket representing a successful connection to a remote
46 //      Cast Receiver's agent.
47 //   2. Sends a LAUNCH request to the Cast Receiver to start its Mirroring App.
48 //   3. Waits for a RECEIVER_STATUS message from the Receiver indicating launch
49 //      success, or a LAUNCH_ERROR.
50 //   4. Once launched, message routing (i.e., a VirtualConnection) is requested,
51 //      for messaging between the SenderSession (locally) and the remote
52 //      Mirroring App.
53 //   5. Once message routing is established, the local SenderSession is created
54 //      and begins the mirroring-specific OFFER/ANSWER messaging to negotiate
55 //      the streaming parameters.
56 //   6. Streaming commences.
57 //
58 // If at any point an error occurs, the LoopingFileCastAgent executes a clean
59 // shut-down (both locally, and with the remote Cast Receiver), and then invokes
60 // the ShutdownCallback that was passed to the constructor.
61 //
62 // Normal shutdown happens when either:
63 //
64 //   1. Receiver-side, the Mirroring App is shut down. This will cause the
65 //      ShutdownCallback passed to the constructor to be invoked.
66 //   2. This LoopingFileCastAgent is destroyed (automatic shutdown is part of
67 //      the destruction procedure).
68 class LoopingFileCastAgent final
69     : public SenderSocketFactory::Client,
70       public VirtualConnectionRouter::SocketErrorHandler,
71       public ConnectionNamespaceHandler::VirtualConnectionPolicy,
72       public CastMessageHandler,
73       public SenderSession::Client,
74       public RemotingSender::Client {
75  public:
76   using ShutdownCallback = std::function<void()>;
77 
78   // |shutdown_callback| is invoked after normal shutdown, whether initiated
79   // sender- or receiver-side; or, for any fatal error.
80   LoopingFileCastAgent(TaskRunner* task_runner,
81                        ShutdownCallback shutdown_callback);
82   ~LoopingFileCastAgent();
83 
84   // Connect to a Cast Receiver, and start the workflow to establish a
85   // mirroring/streaming session. Destroy the LoopingFileCastAgent to shutdown
86   // and disconnect.
87   void Connect(ConnectionSettings settings);
88 
89  private:
90   // SenderSocketFactory::Client overrides.
91   void OnConnected(SenderSocketFactory* factory,
92                    const IPEndpoint& endpoint,
93                    std::unique_ptr<CastSocket> socket) override;
94   void OnError(SenderSocketFactory* factory,
95                const IPEndpoint& endpoint,
96                Error error) override;
97 
98   // VirtualConnectionRouter::SocketErrorHandler overrides.
99   void OnClose(CastSocket* cast_socket) override;
100   void OnError(CastSocket* socket, Error error) override;
101 
102   // ConnectionNamespaceHandler::VirtualConnectionPolicy overrides.
103   bool IsConnectionAllowed(
104       const VirtualConnection& virtual_conn) const override;
105 
106   // CastMessageHandler overrides.
107   void OnMessage(VirtualConnectionRouter* router,
108                  CastSocket* socket,
109                  ::cast::channel::CastMessage message) override;
110 
111   // RemotingSender::Client overrides.
112   void OnReady() override;
113   void OnPlaybackRateChange(double rate) override;
114 
115   // Returns the Cast application ID for either A/V mirroring or audio-only
116   // mirroring, as configured by the ConnectionSettings.
117   const char* GetMirroringAppId() const;
118 
119   // Called by OnMessage() to determine whether the Cast Receiver has launched
120   // or unlaunched the Mirroring App. If the former, a VirtualConnection is
121   // requested. Otherwise, the workflow is aborted and Shutdown() is called.
122   void HandleReceiverStatus(const Json::Value& status);
123 
124   // Called by the |connection_handler_| after message routing to the Cast
125   // Receiver's Mirroring App has been established (if |success| is true).
126   void OnRemoteMessagingOpened(bool success);
127 
128   // Once we have a connection to the receiver we need to create and start
129   // a sender session. This method results in the OFFER/ANSWER exchange
130   // being completed and a session should be started.
131   void CreateAndStartSession();
132 
133   // SenderSession::Client overrides.
134   void OnNegotiated(const SenderSession* session,
135                     SenderSession::ConfiguredSenders senders,
136                     capture_recommendations::Recommendations
137                         capture_recommendations) override;
138   void OnRemotingNegotiated(
139       const SenderSession* session,
140       SenderSession::RemotingNegotiation negotiation) override;
141   void OnError(const SenderSession* session, Error error) override;
142 
143   // Starts the remoting sender. This may occur when remoting is "ready" if the
144   // session is already negotiated, or upon session negotiation if the receiver
145   // is already ready.
146   void StartRemotingSenders();
147 
148   // Helper for stopping the current session, and/or unwinding a remote
149   // connection request (pre-session). This ensures LoopingFileCastAgent is in a
150   // terminal shutdown state.
151   void Shutdown();
152 
153   // Member variables set as part of construction.
154   TaskRunner* const task_runner_;
155   ShutdownCallback shutdown_callback_;
156   VirtualConnectionRouter router_;
157   ConnectionNamespaceHandler connection_handler_;
158   SenderSocketFactory socket_factory_;
159   std::unique_ptr<TlsConnectionFactory> connection_factory_;
160   CastSocketMessagePort message_port_;
161 
162   // Counter for distinguishing request messages sent to the Cast Receiver.
163   int next_request_id_ = 1;
164 
165   // Initialized by Connect().
166   absl::optional<ConnectionSettings> connection_settings_;
167   SerialDeletePtr<ScopedWakeLock> wake_lock_;
168 
169   // If non-empty, this is the sessionId associated with the Cast Receiver
170   // application that this LoopingFileCastAgent launched.
171   std::string app_session_id_;
172 
173   // This is set once LoopingFileCastAgent has requested to start messaging to
174   // the mirroring app on a Cast Receiver.
175   absl::optional<VirtualConnection> remote_connection_;
176 
177   // Member variables set while a streaming to the mirroring app on a Cast
178   // Receiver.
179   std::unique_ptr<Environment> environment_;
180   std::unique_ptr<SenderSession> current_session_;
181   std::unique_ptr<LoopingFileSender> file_sender_;
182 
183   // Remoting specific member variables.
184   std::unique_ptr<RemotingSender> remoting_sender_;
185 
186   // Set when remoting is successfully negotiated. However, remoting streams
187   // won't start until |is_ready_for_remoting_| is true.
188   std::unique_ptr<SenderSession::RemotingNegotiation> current_negotiation_;
189 
190   // Set to true when the remoting receiver is ready.  However, remoting streams
191   // won't start until remoting is successfully negotiated.
192   bool is_ready_for_remoting_ = false;
193 };
194 
195 }  // namespace cast
196 }  // namespace openscreen
197 
198 #endif  // CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_
199