1 // Copyright 2018 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 OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_ 6 #define OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_ 7 8 #include <map> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "osp/msgs/osp_messages.h" 14 #include "osp/public/message_demuxer.h" 15 #include "osp/public/presentation/presentation_connection.h" 16 17 namespace openscreen { 18 namespace osp { 19 20 enum class ResponseResult { 21 kSuccess = 0, 22 kInvalidUrl, 23 kRequestTimedOut, 24 kRequestFailedTransient, 25 kRequestFailedPermanent, 26 kHttpError, 27 kUnknown, 28 }; 29 30 class ReceiverDelegate { 31 public: 32 virtual ~ReceiverDelegate() = default; 33 34 // Called when the availability (compatible, not compatible, or invalid) 35 // for specific URLs is needed to be supplied by the delegate. 36 // See "#presentation-protocol" spec section. 37 // Returns a list of url availabilities. 38 virtual std::vector<msgs::UrlAvailability> OnUrlAvailabilityRequest( 39 uint64_t watch_id, 40 uint64_t watch_duration, 41 std::vector<std::string> urls) = 0; 42 43 // Called when a new presentation is requested by a controller. This should 44 // return true if the presentation was accepted, false otherwise. 45 virtual bool StartPresentation( 46 const Connection::PresentationInfo& info, 47 uint64_t source_id, 48 const std::vector<msgs::HttpHeader>& http_headers) = 0; 49 50 // Called when the receiver wants to actually connection to the presentation. 51 // Should return true if the connection was successful, false otherwise. 52 virtual bool ConnectToPresentation(uint64_t request_id, 53 const std::string& id, 54 uint64_t source_id) = 0; 55 56 // Called when a presentation is requested to be terminated by a controller. 57 virtual void TerminatePresentation(const std::string& id, 58 TerminationReason reason) = 0; 59 }; 60 61 class Receiver final : public MessageDemuxer::MessageCallback, 62 public Connection::ParentDelegate { 63 public: 64 // TODO(crbug.com/openscreen/31): Remove singletons in the embedder API and 65 // protocol implementation layers. 66 static Receiver* Get(); 67 void Init(); 68 void Deinit(); 69 70 // Sets the object to call when a new receiver connection is available. 71 // |delegate| must either outlive PresentationReceiver or live until a new 72 // delegate (possibly nullptr) is set. Setting the delegate to nullptr will 73 // automatically ignore all future receiver requests. 74 void SetReceiverDelegate(ReceiverDelegate* delegate); 75 76 // Called by the embedder to report its response to StartPresentation. 77 Error OnPresentationStarted(const std::string& presentation_id, 78 Connection* connection, 79 ResponseResult result); 80 81 Error OnConnectionCreated(uint64_t request_id, 82 Connection* connection, 83 ResponseResult result); 84 85 // Connection::ParentDelegate overrides. 86 Error CloseConnection(Connection* connection, 87 Connection::CloseReason reason) override; 88 // Also called by the embedder to report that a presentation has been 89 // terminated. 90 Error OnPresentationTerminated(const std::string& presentation_id, 91 TerminationReason reason) override; 92 void OnConnectionDestroyed(Connection* connection) override; 93 94 // MessageDemuxer::MessageCallback overrides. 95 ErrorOr<size_t> OnStreamMessage(uint64_t endpoint_id, 96 uint64_t connection_id, 97 msgs::Type message_type, 98 const uint8_t* buffer, 99 size_t buffer_size, 100 Clock::time_point now) override; 101 102 private: 103 struct QueuedResponse { 104 enum class Type { kInitiation, kConnection }; 105 106 Type type; 107 uint64_t request_id; 108 uint64_t connection_id; 109 uint64_t endpoint_id; 110 }; 111 112 struct Presentation { 113 uint64_t endpoint_id; 114 MessageDemuxer::MessageWatch terminate_watch; 115 uint64_t terminate_request_id; 116 std::vector<Connection*> connections; 117 }; 118 119 Receiver(); 120 ~Receiver() override; 121 122 using QueuedResponseIterator = std::vector<QueuedResponse>::const_iterator; 123 124 void DeleteQueuedResponse(const std::string& presentation_id, 125 QueuedResponseIterator response); 126 ErrorOr<QueuedResponseIterator> GetQueuedResponse( 127 const std::string& presentation_id, 128 uint64_t request_id) const; 129 130 ReceiverDelegate* delegate_ = nullptr; 131 132 // TODO(jophba): scope requests by endpoint, not presentation. This doesn't 133 // work properly for multiple controllers. 134 std::map<std::string, std::vector<QueuedResponse>> queued_responses_; 135 136 // Presentations are added when the embedder starts the presentation, 137 // and ended when a new receiver delegate is set or when 138 // a presentation is called to be terminated (OnPresentationTerminated). 139 std::map<std::string, Presentation> started_presentations_; 140 141 std::unique_ptr<ConnectionManager> connection_manager_; 142 143 MessageDemuxer::MessageWatch availability_watch_; 144 MessageDemuxer::MessageWatch initiation_watch_; 145 MessageDemuxer::MessageWatch connection_watch_; 146 147 uint64_t GetNextConnectionId(); 148 }; 149 150 } // namespace osp 151 } // namespace openscreen 152 153 #endif // OSP_PUBLIC_PRESENTATION_PRESENTATION_RECEIVER_H_ 154