Music Hub  ..
A session-wide music playback service
pulse_audio_output_observer.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2014 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  * Ricardo Mendoza <ricardo.mendoza@canonical.com>
18  */
19 #ifndef CORE_UBUNTU_MEDIA_AUDIO_PULSE_AUDIO_OUTPUT_OBSERVER_H_
20 #define CORE_UBUNTU_MEDIA_AUDIO_PULSE_AUDIO_OUTPUT_OBSERVER_H_
21 
23 
24 #include <iosfwd>
25 #include <memory>
26 #include <regex>
27 
28 namespace core
29 {
30 namespace ubuntu
31 {
32 namespace media
33 {
34 namespace audio
35 {
36 // Implements the audio::OutputObserver interface
37 // relying on pulse to query the connected ports
38 // of the primary card of the system.
40 {
41 public:
42  // Save us some typing.
43  typedef std::shared_ptr<PulseAudioOutputObserver> Ptr;
44 
45  // Reporter is responsible for surfacing events from the implementation
46  // that help in resolving/tracking down issues. Default implementation is empty.
47  struct Reporter
48  {
49  // To save us some typing.
50  typedef std::shared_ptr<Reporter> Ptr;
51 
52  // Simple type to help in reporting.
53  struct Port
54  {
55  // Returns true iff the name of both ports are equal.
56  bool operator==(const Port& rhs) const;
57  // Returns true iff the name of the ports differ.
58  bool operator<(const Port& rhs) const;
59 
60  std::string name; // The name of the port.
61  std::string description; // Human-readable description of the port.
62  bool is_available; // True if the port is available.
63  bool is_monitored; // True if the port is monitored by the observer.
64  };
65 
66  virtual ~Reporter();
67  // connected_to_pulse_audio is called when a connection with pulse has been established.
68  virtual void connected_to_pulse_audio();
69  // query_for_default_sink_failed is called when no default sink was returned.
70  virtual void query_for_default_sink_failed();
71  // query_for_default_sink_finished is called when the default sink query against pulse
72  // has finished, reporting the name of the sink to observers.
73  virtual void query_for_default_sink_finished(const std::string& sink_name);
74  // query_for_sink_info_finished is called when a query for information about a specific sink
75  // has finished, reporting the name, index of the sink as well as the set of ports known to the sink.
76  virtual void query_for_sink_info_finished(const std::string& name, std::uint32_t index, const std::set<Port>& known_ports);
77  // sink_event_with_index is called when something happened on a sink, reporing the index of the
78  // sink.
79  virtual void sink_event_with_index(std::uint32_t index);
80  };
81 
82  // Construction time arguments go here
84  {
85  // Name of the sink that we should consider.
86  std::string sink
87  {
88  // A special value that requests the implementation to
89  // query pulseaudio for the default configured sink.
90  "query.from.server"
91  };
92  // Output port name patterns that should be observed on the configured sink.
93  // All patterns have to be valid regular expressions.
94  std::vector<std::regex> output_port_patterns
95  {
96  // Any port is considered with this special value.
97  std::regex{".+"}
98  };
99  // The Reporter instance that the implementation reports
100  // events to. Must not be null.
101  Reporter::Ptr reporter{std::make_shared<Reporter>()};
102  };
103 
104  // Constructs a new instance, throws:
105  // * std::runtime_error if connection to pulseaudio fails.
106  // * std::runtime_error if reporter instance is null.
108 
109  // We provide the name of the sink we are connecting to as a
110  // getable/observable property. This is specifically meant for
111  // consumption by test code.
112  const core::Property<std::string>& sink() const;
113  // The set of ports that have been identified on the configured sink.
114  // Specifically meant for consumption by test code.
115  const core::Property<std::set<Reporter::Port>>& known_ports() const;
116  // Getable/observable property holding the state of external outputs.
117  const core::Property<OutputState>& external_output_state() const override;
118 
119 private:
120  struct Private;
121  std::shared_ptr<Private> d;
122 };
123 }
124 }
125 }
126 }
127 
128 #endif // CORE_UBUNTU_MEDIA_AUDIO_PULSE_AUDIO_OUTPUT_OBSERVER_H_
const core::Property< OutputState > & external_output_state() const override
Definition: player.h:33
const core::Property< std::string > & sink() const
virtual void query_for_sink_info_finished(const std::string &name, std::uint32_t index, const std::set< Port > &known_ports)
const core::Property< std::set< Reporter::Port > > & known_ports() const