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_SERVICE_LISTENER_H_ 6 #define OSP_PUBLIC_SERVICE_LISTENER_H_ 7 8 #include <cstdint> 9 #include <string> 10 #include <vector> 11 12 #include "osp/public/service_info.h" 13 #include "osp/public/timestamp.h" 14 #include "platform/base/macros.h" 15 16 namespace openscreen { 17 namespace osp { 18 19 // Used to report an error from a ServiceListener implementation. 20 struct ServiceListenerError { 21 public: 22 // TODO(mfoltz): Add additional error types, as implementations progress. 23 enum class Code { 24 kNone = 0, 25 }; 26 27 ServiceListenerError(); 28 ServiceListenerError(Code error, const std::string& message); 29 ServiceListenerError(const ServiceListenerError& other); 30 ~ServiceListenerError(); 31 32 ServiceListenerError& operator=(const ServiceListenerError& other); 33 34 Code error; 35 std::string message; 36 }; 37 38 class ServiceListener { 39 public: 40 enum class State { 41 kStopped = 0, 42 kStarting, 43 kRunning, 44 kStopping, 45 kSearching, 46 kSuspended, 47 }; 48 49 // Holds a set of metrics, captured over a specific range of time, about the 50 // behavior of a ServiceListener instance. 51 struct Metrics { 52 Metrics(); 53 ~Metrics(); 54 55 // The range of time over which the metrics were collected; end_timestamp > 56 // start_timestamp 57 timestamp_t start_timestamp = 0; 58 timestamp_t end_timestamp = 0; 59 60 // The number of packets and bytes sent over the timestamp range. 61 uint64_t num_packets_sent = 0; 62 uint64_t num_bytes_sent = 0; 63 64 // The number of packets and bytes received over the timestamp range. 65 uint64_t num_packets_received = 0; 66 uint64_t num_bytes_received = 0; 67 68 // The maximum number of receivers discovered over the timestamp range. The 69 // latter two fields break this down by receivers advertising ipv4 and ipv6 70 // endpoints. 71 size_t num_receivers = 0; 72 size_t num_ipv4_receivers = 0; 73 size_t num_ipv6_receivers = 0; 74 }; 75 76 class Observer { 77 public: 78 virtual ~Observer() = default; 79 80 // Called when the state becomes kRunning. 81 virtual void OnStarted() = 0; 82 // Called when the state becomes kStopped. 83 virtual void OnStopped() = 0; 84 // Called when the state becomes kSuspended. 85 virtual void OnSuspended() = 0; 86 // Called when the state becomes kSearching. 87 virtual void OnSearching() = 0; 88 89 // Notifications to changes to the listener's receiver list. 90 virtual void OnReceiverAdded(const ServiceInfo&) = 0; 91 virtual void OnReceiverChanged(const ServiceInfo&) = 0; 92 virtual void OnReceiverRemoved(const ServiceInfo&) = 0; 93 // Called if all receivers are no longer available, e.g. all network 94 // interfaces have been disabled. 95 virtual void OnAllReceiversRemoved() = 0; 96 97 // Reports an error. 98 virtual void OnError(ServiceListenerError) = 0; 99 100 // Reports metrics. 101 virtual void OnMetrics(Metrics) = 0; 102 }; 103 104 virtual ~ServiceListener(); 105 106 // Starts listening for receivers using the config object. 107 // Returns true if state() == kStopped and the service will be started, false 108 // otherwise. 109 virtual bool Start() = 0; 110 111 // Starts the listener in kSuspended mode. This could be used to enable 112 // immediate search via SearchNow() in the future. 113 // Returns true if state() == kStopped and the service will be started, false 114 // otherwise. 115 virtual bool StartAndSuspend() = 0; 116 117 // Stops listening and cancels any search in progress. 118 // Returns true if state() != (kStopped|kStopping). 119 virtual bool Stop() = 0; 120 121 // Suspends background listening. For example, the tab wanting receiver 122 // availability might go in the background, meaning we can suspend listening 123 // to save power. 124 // Returns true if state() == (kRunning|kSearching|kStarting), meaning the 125 // suspension will take effect. 126 virtual bool Suspend() = 0; 127 128 // Resumes listening. Returns true if state() == (kSuspended|kSearching). 129 virtual bool Resume() = 0; 130 131 // Asks the listener to search for receivers now, even if the listener is 132 // is currently suspended. If a background search is already in 133 // progress, this has no effect. Returns true if state() == 134 // (kRunning|kSuspended). 135 virtual bool SearchNow() = 0; 136 137 virtual void AddObserver(Observer* observer) = 0; 138 virtual void RemoveObserver(Observer* observer) = 0; 139 140 // Returns the current state of the listener. state()141 State state() const { return state_; } 142 143 // Returns the last error reported by this listener. last_error()144 const ServiceListenerError& last_error() const { return last_error_; } 145 146 // Returns the current list of receivers known to the ServiceListener. 147 virtual const std::vector<ServiceInfo>& GetReceivers() const = 0; 148 149 protected: 150 ServiceListener(); 151 152 State state_; 153 ServiceListenerError last_error_; 154 std::vector<Observer*> observers_; 155 156 OSP_DISALLOW_COPY_AND_ASSIGN(ServiceListener); 157 }; 158 159 } // namespace osp 160 } // namespace openscreen 161 162 #endif // OSP_PUBLIC_SERVICE_LISTENER_H_ 163