android13/external/openscreen/cast/standalone_sender/looping_file_cast_agent.h

199 lines
8.0 KiB
C++

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_
#define CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_
#include <openssl/x509.h>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "cast/common/channel/cast_message_handler.h"
#include "cast/common/channel/cast_socket_message_port.h"
#include "cast/common/channel/connection_namespace_handler.h"
#include "cast/common/channel/virtual_connection_router.h"
#include "cast/common/public/cast_socket.h"
#include "cast/sender/public/sender_socket_factory.h"
#include "cast/standalone_sender/connection_settings.h"
#include "cast/standalone_sender/looping_file_sender.h"
#include "cast/standalone_sender/remoting_sender.h"
#include "cast/streaming/environment.h"
#include "cast/streaming/sender_session.h"
#include "platform/api/scoped_wake_lock.h"
#include "platform/api/serial_delete_ptr.h"
#include "platform/base/error.h"
#include "platform/base/interface_info.h"
#include "platform/impl/task_runner.h"
namespace Json {
class Value;
}
namespace openscreen {
namespace cast {
// A single-use sender-side Cast Agent that manages the workflow for a mirroring
// session, casting the content from a local file indefinitely. After being
// constructed and having its Connect() method called, the LoopingFileCastAgent
// steps through the following workflow:
//
// 1. Waits for a CastSocket representing a successful connection to a remote
// Cast Receiver's agent.
// 2. Sends a LAUNCH request to the Cast Receiver to start its Mirroring App.
// 3. Waits for a RECEIVER_STATUS message from the Receiver indicating launch
// success, or a LAUNCH_ERROR.
// 4. Once launched, message routing (i.e., a VirtualConnection) is requested,
// for messaging between the SenderSession (locally) and the remote
// Mirroring App.
// 5. Once message routing is established, the local SenderSession is created
// and begins the mirroring-specific OFFER/ANSWER messaging to negotiate
// the streaming parameters.
// 6. Streaming commences.
//
// If at any point an error occurs, the LoopingFileCastAgent executes a clean
// shut-down (both locally, and with the remote Cast Receiver), and then invokes
// the ShutdownCallback that was passed to the constructor.
//
// Normal shutdown happens when either:
//
// 1. Receiver-side, the Mirroring App is shut down. This will cause the
// ShutdownCallback passed to the constructor to be invoked.
// 2. This LoopingFileCastAgent is destroyed (automatic shutdown is part of
// the destruction procedure).
class LoopingFileCastAgent final
: public SenderSocketFactory::Client,
public VirtualConnectionRouter::SocketErrorHandler,
public ConnectionNamespaceHandler::VirtualConnectionPolicy,
public CastMessageHandler,
public SenderSession::Client,
public RemotingSender::Client {
public:
using ShutdownCallback = std::function<void()>;
// |shutdown_callback| is invoked after normal shutdown, whether initiated
// sender- or receiver-side; or, for any fatal error.
LoopingFileCastAgent(TaskRunner* task_runner,
ShutdownCallback shutdown_callback);
~LoopingFileCastAgent();
// Connect to a Cast Receiver, and start the workflow to establish a
// mirroring/streaming session. Destroy the LoopingFileCastAgent to shutdown
// and disconnect.
void Connect(ConnectionSettings settings);
private:
// SenderSocketFactory::Client overrides.
void OnConnected(SenderSocketFactory* factory,
const IPEndpoint& endpoint,
std::unique_ptr<CastSocket> socket) override;
void OnError(SenderSocketFactory* factory,
const IPEndpoint& endpoint,
Error error) override;
// VirtualConnectionRouter::SocketErrorHandler overrides.
void OnClose(CastSocket* cast_socket) override;
void OnError(CastSocket* socket, Error error) override;
// ConnectionNamespaceHandler::VirtualConnectionPolicy overrides.
bool IsConnectionAllowed(
const VirtualConnection& virtual_conn) const override;
// CastMessageHandler overrides.
void OnMessage(VirtualConnectionRouter* router,
CastSocket* socket,
::cast::channel::CastMessage message) override;
// RemotingSender::Client overrides.
void OnReady() override;
void OnPlaybackRateChange(double rate) override;
// Returns the Cast application ID for either A/V mirroring or audio-only
// mirroring, as configured by the ConnectionSettings.
const char* GetMirroringAppId() const;
// Called by OnMessage() to determine whether the Cast Receiver has launched
// or unlaunched the Mirroring App. If the former, a VirtualConnection is
// requested. Otherwise, the workflow is aborted and Shutdown() is called.
void HandleReceiverStatus(const Json::Value& status);
// Called by the |connection_handler_| after message routing to the Cast
// Receiver's Mirroring App has been established (if |success| is true).
void OnRemoteMessagingOpened(bool success);
// Once we have a connection to the receiver we need to create and start
// a sender session. This method results in the OFFER/ANSWER exchange
// being completed and a session should be started.
void CreateAndStartSession();
// SenderSession::Client overrides.
void OnNegotiated(const SenderSession* session,
SenderSession::ConfiguredSenders senders,
capture_recommendations::Recommendations
capture_recommendations) override;
void OnRemotingNegotiated(
const SenderSession* session,
SenderSession::RemotingNegotiation negotiation) override;
void OnError(const SenderSession* session, Error error) override;
// Starts the remoting sender. This may occur when remoting is "ready" if the
// session is already negotiated, or upon session negotiation if the receiver
// is already ready.
void StartRemotingSenders();
// Helper for stopping the current session, and/or unwinding a remote
// connection request (pre-session). This ensures LoopingFileCastAgent is in a
// terminal shutdown state.
void Shutdown();
// Member variables set as part of construction.
TaskRunner* const task_runner_;
ShutdownCallback shutdown_callback_;
VirtualConnectionRouter router_;
ConnectionNamespaceHandler connection_handler_;
SenderSocketFactory socket_factory_;
std::unique_ptr<TlsConnectionFactory> connection_factory_;
CastSocketMessagePort message_port_;
// Counter for distinguishing request messages sent to the Cast Receiver.
int next_request_id_ = 1;
// Initialized by Connect().
absl::optional<ConnectionSettings> connection_settings_;
SerialDeletePtr<ScopedWakeLock> wake_lock_;
// If non-empty, this is the sessionId associated with the Cast Receiver
// application that this LoopingFileCastAgent launched.
std::string app_session_id_;
// This is set once LoopingFileCastAgent has requested to start messaging to
// the mirroring app on a Cast Receiver.
absl::optional<VirtualConnection> remote_connection_;
// Member variables set while a streaming to the mirroring app on a Cast
// Receiver.
std::unique_ptr<Environment> environment_;
std::unique_ptr<SenderSession> current_session_;
std::unique_ptr<LoopingFileSender> file_sender_;
// Remoting specific member variables.
std::unique_ptr<RemotingSender> remoting_sender_;
// Set when remoting is successfully negotiated. However, remoting streams
// won't start until |is_ready_for_remoting_| is true.
std::unique_ptr<SenderSession::RemotingNegotiation> current_negotiation_;
// Set to true when the remoting receiver is ready. However, remoting streams
// won't start until remoting is successfully negotiated.
bool is_ready_for_remoting_ = false;
};
} // namespace cast
} // namespace openscreen
#endif // CAST_STANDALONE_SENDER_LOOPING_FILE_CAST_AGENT_H_