aboutsummaryrefslogtreecommitdiff
path: root/osp/public/service_listener.h
blob: 2a11e44c42beec3e1814261a3c5ecaafe23be257 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// 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_SERVICE_LISTENER_H_
#define OSP_PUBLIC_SERVICE_LISTENER_H_

#include <cstdint>
#include <string>
#include <vector>

#include "osp/public/service_info.h"
#include "osp/public/timestamp.h"
#include "platform/base/macros.h"

namespace openscreen {
namespace osp {

// Used to report an error from a ServiceListener implementation.
struct ServiceListenerError {
 public:
  // TODO(mfoltz): Add additional error types, as implementations progress.
  enum class Code {
    kNone = 0,
  };

  ServiceListenerError();
  ServiceListenerError(Code error, const std::string& message);
  ServiceListenerError(const ServiceListenerError& other);
  ~ServiceListenerError();

  ServiceListenerError& operator=(const ServiceListenerError& other);

  Code error;
  std::string message;
};

class ServiceListener {
 public:
  enum class State {
    kStopped = 0,
    kStarting,
    kRunning,
    kStopping,
    kSearching,
    kSuspended,
  };

  // Holds a set of metrics, captured over a specific range of time, about the
  // behavior of a ServiceListener instance.
  struct Metrics {
    Metrics();
    ~Metrics();

    // The range of time over which the metrics were collected; end_timestamp >
    // start_timestamp
    timestamp_t start_timestamp = 0;
    timestamp_t end_timestamp = 0;

    // The number of packets and bytes sent over the timestamp range.
    uint64_t num_packets_sent = 0;
    uint64_t num_bytes_sent = 0;

    // The number of packets and bytes received over the timestamp range.
    uint64_t num_packets_received = 0;
    uint64_t num_bytes_received = 0;

    // The maximum number of receivers discovered over the timestamp range.  The
    // latter two fields break this down by receivers advertising ipv4 and ipv6
    // endpoints.
    size_t num_receivers = 0;
    size_t num_ipv4_receivers = 0;
    size_t num_ipv6_receivers = 0;
  };

  class Observer {
   public:
    virtual ~Observer() = default;

    // Called when the state becomes kRunning.
    virtual void OnStarted() = 0;
    // Called when the state becomes kStopped.
    virtual void OnStopped() = 0;
    // Called when the state becomes kSuspended.
    virtual void OnSuspended() = 0;
    // Called when the state becomes kSearching.
    virtual void OnSearching() = 0;

    // Notifications to changes to the listener's receiver list.
    virtual void OnReceiverAdded(const ServiceInfo&) = 0;
    virtual void OnReceiverChanged(const ServiceInfo&) = 0;
    virtual void OnReceiverRemoved(const ServiceInfo&) = 0;
    // Called if all receivers are no longer available, e.g. all network
    // interfaces have been disabled.
    virtual void OnAllReceiversRemoved() = 0;

    // Reports an error.
    virtual void OnError(ServiceListenerError) = 0;

    // Reports metrics.
    virtual void OnMetrics(Metrics) = 0;
  };

  virtual ~ServiceListener();

  // Starts listening for receivers using the config object.
  // Returns true if state() == kStopped and the service will be started, false
  // otherwise.
  virtual bool Start() = 0;

  // Starts the listener in kSuspended mode.  This could be used to enable
  // immediate search via SearchNow() in the future.
  // Returns true if state() == kStopped and the service will be started, false
  // otherwise.
  virtual bool StartAndSuspend() = 0;

  // Stops listening and cancels any search in progress.
  // Returns true if state() != (kStopped|kStopping).
  virtual bool Stop() = 0;

  // Suspends background listening. For example, the tab wanting receiver
  // availability might go in the background, meaning we can suspend listening
  // to save power.
  // Returns true if state() == (kRunning|kSearching|kStarting), meaning the
  // suspension will take effect.
  virtual bool Suspend() = 0;

  // Resumes listening.  Returns true if state() == (kSuspended|kSearching).
  virtual bool Resume() = 0;

  // Asks the listener to search for receivers now, even if the listener is
  // is currently suspended.  If a background search is already in
  // progress, this has no effect.  Returns true if state() ==
  // (kRunning|kSuspended).
  virtual bool SearchNow() = 0;

  virtual void AddObserver(Observer* observer) = 0;
  virtual void RemoveObserver(Observer* observer) = 0;

  // Returns the current state of the listener.
  State state() const { return state_; }

  // Returns the last error reported by this listener.
  const ServiceListenerError& last_error() const { return last_error_; }

  // Returns the current list of receivers known to the ServiceListener.
  virtual const std::vector<ServiceInfo>& GetReceivers() const = 0;

 protected:
  ServiceListener();

  State state_;
  ServiceListenerError last_error_;
  std::vector<Observer*> observers_;

  OSP_DISALLOW_COPY_AND_ASSIGN(ServiceListener);
};

}  // namespace osp
}  // namespace openscreen

#endif  // OSP_PUBLIC_SERVICE_LISTENER_H_