You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
8.3 KiB
224 lines
8.3 KiB
// Copyright 2018 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 OSP_PUBLIC_PRESENTATION_PRESENTATION_CONTROLLER_H_
|
|
#define OSP_PUBLIC_PRESENTATION_PRESENTATION_CONTROLLER_H_
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "absl/strings/string_view.h"
|
|
#include "absl/types/optional.h"
|
|
#include "osp/public/presentation/presentation_connection.h"
|
|
#include "osp/public/protocol_connection.h"
|
|
#include "osp/public/service_listener.h"
|
|
#include "platform/api/time.h"
|
|
#include "platform/base/error.h"
|
|
|
|
namespace openscreen {
|
|
namespace osp {
|
|
|
|
class UrlAvailabilityRequester;
|
|
|
|
class RequestDelegate {
|
|
public:
|
|
virtual ~RequestDelegate() = default;
|
|
|
|
virtual void OnConnection(std::unique_ptr<Connection> connection) = 0;
|
|
virtual void OnError(const Error& error) = 0;
|
|
};
|
|
|
|
class ReceiverObserver {
|
|
public:
|
|
virtual ~ReceiverObserver() = default;
|
|
|
|
// Called when there is an unrecoverable error in requesting availability.
|
|
// This means the availability is unknown and there is no further response to
|
|
// wait for.
|
|
virtual void OnRequestFailed(const std::string& presentation_url,
|
|
const std::string& service_id) = 0;
|
|
|
|
// Called when receivers compatible with |presentation_url| are known to be
|
|
// available.
|
|
virtual void OnReceiverAvailable(const std::string& presentation_url,
|
|
const std::string& service_id) = 0;
|
|
// Only called for |service_id| values previously advertised as available.
|
|
virtual void OnReceiverUnavailable(const std::string& presentation_url,
|
|
const std::string& service_id) = 0;
|
|
};
|
|
|
|
class Controller final : public ServiceListener::Observer,
|
|
public Connection::ParentDelegate {
|
|
public:
|
|
class ReceiverWatch {
|
|
public:
|
|
ReceiverWatch();
|
|
ReceiverWatch(Controller* controller,
|
|
const std::vector<std::string>& urls,
|
|
ReceiverObserver* observer);
|
|
ReceiverWatch(ReceiverWatch&&) noexcept;
|
|
~ReceiverWatch();
|
|
|
|
ReceiverWatch& operator=(ReceiverWatch);
|
|
|
|
explicit operator bool() const { return observer_; }
|
|
|
|
friend void swap(ReceiverWatch& a, ReceiverWatch& b);
|
|
|
|
private:
|
|
std::vector<std::string> urls_;
|
|
ReceiverObserver* observer_ = nullptr;
|
|
Controller* controller_ = nullptr;
|
|
};
|
|
|
|
class ConnectRequest {
|
|
public:
|
|
ConnectRequest();
|
|
ConnectRequest(Controller* controller,
|
|
const std::string& service_id,
|
|
bool is_reconnect,
|
|
absl::optional<uint64_t> request_id);
|
|
ConnectRequest(ConnectRequest&&) noexcept;
|
|
~ConnectRequest();
|
|
|
|
ConnectRequest& operator=(ConnectRequest);
|
|
|
|
explicit operator bool() const { return request_id_.has_value(); }
|
|
|
|
friend void swap(ConnectRequest& a, ConnectRequest& b);
|
|
|
|
private:
|
|
std::string service_id_;
|
|
bool is_reconnect_;
|
|
absl::optional<uint64_t> request_id_;
|
|
Controller* controller_;
|
|
};
|
|
|
|
explicit Controller(ClockNowFunctionPtr now_function);
|
|
~Controller();
|
|
|
|
// Requests receivers compatible with all urls in |urls| and registers
|
|
// |observer| for availability changes. The screens will be a subset of the
|
|
// screen list maintained by the ServiceListener. Returns an RAII object that
|
|
// tracks the registration.
|
|
ReceiverWatch RegisterReceiverWatch(const std::vector<std::string>& urls,
|
|
ReceiverObserver* observer);
|
|
|
|
// Requests that a new presentation be created on |service_id| using
|
|
// |presentation_url|, with the result passed to |delegate|.
|
|
// |conn_delegate| is passed to the resulting connection. The returned
|
|
// ConnectRequest object may be destroyed before any |delegate| methods are
|
|
// called to cancel the request.
|
|
ConnectRequest StartPresentation(const std::string& url,
|
|
const std::string& service_id,
|
|
RequestDelegate* delegate,
|
|
Connection::Delegate* conn_delegate);
|
|
|
|
// Requests reconnection to the presentation with the given id and URL running
|
|
// on |service_id|, with the result passed to |delegate|. |conn_delegate| is
|
|
// passed to the resulting connection. The returned ConnectRequest object may
|
|
// be destroyed before any |delegate| methods are called to cancel the
|
|
// request.
|
|
ConnectRequest ReconnectPresentation(const std::vector<std::string>& urls,
|
|
const std::string& presentation_id,
|
|
const std::string& service_id,
|
|
RequestDelegate* delegate,
|
|
Connection::Delegate* conn_delegate);
|
|
|
|
// Requests reconnection with a previously-connected connection. This both
|
|
// avoids having to respecify the parameters and connection delegate but also
|
|
// simplifies the implementation of the Presentation API requirement to return
|
|
// the same connection object where possible.
|
|
ConnectRequest ReconnectConnection(std::unique_ptr<Connection> connection,
|
|
RequestDelegate* delegate);
|
|
|
|
// Connection::ParentDelegate overrides.
|
|
Error CloseConnection(Connection* connection,
|
|
Connection::CloseReason reason) override;
|
|
|
|
// Also called by the embedder to report that a presentation has been
|
|
// terminated.
|
|
Error OnPresentationTerminated(const std::string& presentation_id,
|
|
TerminationReason reason) override;
|
|
|
|
void OnConnectionDestroyed(Connection* connection) override;
|
|
|
|
// Returns an empty string if no such presentation ID is found.
|
|
std::string GetServiceIdForPresentationId(
|
|
const std::string& presentation_id) const;
|
|
|
|
ProtocolConnection* GetConnectionRequestGroupStream(
|
|
const std::string& service_id);
|
|
|
|
// TODO(btolsch): still used?
|
|
void SetConnectionRequestGroupStreamForTest(
|
|
const std::string& service_id,
|
|
std::unique_ptr<ProtocolConnection> stream);
|
|
|
|
private:
|
|
class TerminationListener;
|
|
class MessageGroupStreams;
|
|
|
|
struct ControlledPresentation {
|
|
std::string service_id;
|
|
std::string url;
|
|
std::vector<Connection*> connections;
|
|
};
|
|
|
|
static std::string MakePresentationId(const std::string& url,
|
|
const std::string& service_id);
|
|
|
|
void AddConnection(Connection* connection);
|
|
void OpenConnection(uint64_t connection_id,
|
|
uint64_t endpoint_id,
|
|
const std::string& service_id,
|
|
RequestDelegate* request_delegate,
|
|
std::unique_ptr<Connection>&& connection,
|
|
std::unique_ptr<ProtocolConnection>&& stream);
|
|
|
|
void TerminatePresentationById(const std::string& presentation_id);
|
|
|
|
// Cancels compatible receiver monitoring for the given |urls|, |observer|
|
|
// pair.
|
|
void CancelReceiverWatch(const std::vector<std::string>& urls,
|
|
ReceiverObserver* observer);
|
|
|
|
// Cancels a presentation connect request for the given |request_id| if one is
|
|
// pending.
|
|
void CancelConnectRequest(const std::string& service_id,
|
|
bool is_reconnect,
|
|
uint64_t request_id);
|
|
|
|
// ServiceListener::Observer overrides.
|
|
void OnStarted() override;
|
|
void OnStopped() override;
|
|
void OnSuspended() override;
|
|
void OnSearching() override;
|
|
void OnReceiverAdded(const ServiceInfo& info) override;
|
|
void OnReceiverChanged(const ServiceInfo& info) override;
|
|
void OnReceiverRemoved(const ServiceInfo& info) override;
|
|
void OnAllReceiversRemoved() override;
|
|
void OnError(ServiceListenerError) override;
|
|
void OnMetrics(ServiceListener::Metrics) override;
|
|
|
|
std::map<std::string, uint64_t> next_connection_id_;
|
|
|
|
std::map<std::string, ControlledPresentation> presentations_;
|
|
|
|
std::unique_ptr<ConnectionManager> connection_manager_;
|
|
|
|
std::unique_ptr<UrlAvailabilityRequester> availability_requester_;
|
|
std::map<std::string, IPEndpoint> receiver_endpoints_;
|
|
|
|
std::map<std::string, std::unique_ptr<MessageGroupStreams>> group_streams_;
|
|
std::map<std::string, std::unique_ptr<TerminationListener>>
|
|
termination_listener_by_id_;
|
|
};
|
|
|
|
} // namespace osp
|
|
} // namespace openscreen
|
|
|
|
#endif // OSP_PUBLIC_PRESENTATION_PRESENTATION_CONTROLLER_H_
|