Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: device/bluetooth/bluetooth_audio_sink_chromeos.cc

Issue 876153002: device/bluetooth:Implement Register() for BluetoothAudioSinkChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved kBluetoothAudioSinkUUID to BluetoothMediaClient. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h" 5 #include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
12
13 namespace {
14
15 // TODO(mcchou): Add the constant to dbus/service_constants.h.
16 const char kBluetoothAudioSinkServicePath[] = "/org/chromium/AudioSink";
17
18 dbus::ObjectPath GenerateEndpointPath() {
19 static unsigned int sequence_number = 0;
20 ++sequence_number;
21 std::stringstream path;
22 path << kBluetoothAudioSinkServicePath << "/endpoint" << sequence_number;
23 return dbus::ObjectPath(path.str());
24 }
25
26 } // namespace
10 27
11 namespace chromeos { 28 namespace chromeos {
12 29
13 BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS( 30 BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS(
14 BluetoothAdapterChromeOS* adapter) 31 scoped_refptr<BluetoothAdapterChromeOS> adapter)
15 : state_(device::BluetoothAudioSink::STATE_INVALID), 32 : state_(device::BluetoothAudioSink::STATE_INVALID),
16 present_(false),
17 powered_(false),
18 volume_(0), 33 volume_(0),
19 read_mtu_(0), 34 read_mtu_(0),
20 write_mtu_(0), 35 write_mtu_(0),
21 adapter_(adapter), 36 adapter_(adapter),
22 weak_ptr_factory_(this) { 37 weak_ptr_factory_(this) {
23 DCHECK(adapter_); 38 DCHECK(adapter_.get());
24 39
25 present_ = adapter_->IsPresent(); 40 if (adapter_->IsPresent() && adapter_->IsPowered())
armansito 2015/01/29 04:22:56 I would DCHECK(adapter_->IsPresent()), since it sh
Miao 2015/01/29 23:58:38 Right, since present is checked in BluetoothAdapte
26 powered_ = adapter_->IsPowered(); 41 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED);
27 if (present_ && powered_)
28 state_ = device::BluetoothAudioSink::STATE_DISCONNECTED;
29 adapter_->AddObserver(this); 42 adapter_->AddObserver(this);
30 } 43 }
31 44
32 BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() { 45 BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() {
33 DCHECK(adapter_); 46 DCHECK(adapter_.get());
34 adapter_->RemoveObserver(this); 47 adapter_->RemoveObserver(this);
35 } 48 }
36 49
37 void BluetoothAudioSinkChromeOS::AddObserver( 50 void BluetoothAudioSinkChromeOS::AddObserver(
38 device::BluetoothAudioSink::Observer* observer) { 51 device::BluetoothAudioSink::Observer* observer) {
39 DCHECK(observer); 52 DCHECK(observer);
40 observers_.AddObserver(observer); 53 observers_.AddObserver(observer);
41 } 54 }
42 55
43 void BluetoothAudioSinkChromeOS::RemoveObserver( 56 void BluetoothAudioSinkChromeOS::RemoveObserver(
44 device::BluetoothAudioSink::Observer* observer) { 57 device::BluetoothAudioSink::Observer* observer) {
45 DCHECK(observer); 58 DCHECK(observer);
46 observers_.RemoveObserver(observer); 59 observers_.RemoveObserver(observer);
47 } 60 }
48 61
49 device::BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const { 62 device::BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const {
50 return state_; 63 return state_;
51 } 64 }
52 65
53 uint16_t BluetoothAudioSinkChromeOS::GetVolume() const { 66 uint16_t BluetoothAudioSinkChromeOS::GetVolume() const {
54 return volume_; 67 return volume_;
55 } 68 }
56 69
57 void BluetoothAudioSinkChromeOS::AdapterPresentChanged( 70 void BluetoothAudioSinkChromeOS::AdapterPresentChanged(
58 device::BluetoothAdapter* adapter, 71 device::BluetoothAdapter* adapter,
59 bool present) { 72 bool present) {
60 // TODO(mcchou): BUG=441581 73 VLOG(1) << "Bluetooth audio sink: Bluetooth adapter present changed: "
61 // If |persent| is true, change state to |STATE_DISCONNECTED| and call 74 << present;
62 // StateChanged(). Otherwise, change state to |STATE_INVALID| and call
63 // StateChanged.
64 }
65 75
66 void BluetoothAudioSinkChromeOS::AdapterPoweredChanged( 76 if (adapter->IsPresent()) {
67 device::BluetoothAdapter* adapter, 77 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED);
68 bool powered) { 78 } else {
69 // TODO(mcchou): BUG=441581 79 StateChanged(device::BluetoothAudioSink::STATE_INVALID);
70 // If |powered| is true, change state to |STATE_DISCONNECTED| and call 80 }
71 // StateChanged(). Otherwise, change state to |STATE_INVALID| and call
72 // StateChanged.
73 } 81 }
74 82
75 void BluetoothAudioSinkChromeOS::MediaRemoved( 83 void BluetoothAudioSinkChromeOS::MediaRemoved(
76 const dbus::ObjectPath& object_path) { 84 const dbus::ObjectPath& object_path) {
77 // TODO(mcchou): BUG=441581 85 // TODO(mcchou): BUG=441581
78 // Check if |object_path| equals to |media_path_|. If true, change the state 86 // Check if |object_path| equals to |media_path_|. If true, change the state
79 // of the audio sink, call StateChanged and reset the audio sink. 87 // of the audio sink, call StateChanged and reset the audio sink.
80 } 88 }
81 89
82 void BluetoothAudioSinkChromeOS::MediaTransportRemoved( 90 void BluetoothAudioSinkChromeOS::MediaTransportRemoved(
83 const dbus::ObjectPath& object_path) { 91 const dbus::ObjectPath& object_path) {
84 // TODO(mcchou): BUG=441581 92 // TODO(mcchou): BUG=441581
85 // Check if |object_path| equals to |transport_path_|. If true, change the 93 // Check if |object_path| equals to |transport_path_|. If true, change the
86 // state of the audio sink, call StateChanged and reset the audio sink. 94 // state of the audio sink, call StateChanged and reset the audio sink.
95 // Whenever powered of |adapter_| turns false while present stays true, media
96 // transport object should be removed accordingly, and the state should be
97 // changed to STATE_DISCONNECTED.
87 } 98 }
88 99
89 void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged( 100 void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged(
90 const dbus::ObjectPath& object_path, 101 const dbus::ObjectPath& object_path,
91 const std::string& property_name) { 102 const std::string& property_name) {
92 // TODO(mcchou): BUG=441581 103 // TODO(mcchou): BUG=441581
93 // Call StateChanged and VolumeChanged accordingly if there is any change on 104 // Call StateChanged and VolumeChanged accordingly if there is any change on
94 // state/volume. 105 // state/volume.
95 } 106 }
96 107
97 void BluetoothAudioSinkChromeOS::SetConfiguration( 108 void BluetoothAudioSinkChromeOS::SetConfiguration(
98 const dbus::ObjectPath& transport_path, 109 const dbus::ObjectPath& transport_path,
99 const dbus::MessageReader& properties) { 110 const dbus::MessageReader& properties) {
100 // TODO(mcchou): BUG=441581 111 // TODO(mcchou): BUG=441581
101 // Update |transport_path_| and store properties if needed. 112 // Update |transport_path_| and store properties if needed.
102 } 113 }
103 114
104 void BluetoothAudioSinkChromeOS::SelectConfiguration( 115 void BluetoothAudioSinkChromeOS::SelectConfiguration(
105 const std::vector<uint8_t>& capabilities, 116 const std::vector<uint8_t>& capabilities,
106 const SelectConfigurationCallback& callback) { 117 const SelectConfigurationCallback& callback) {
107 // TODO(mcchou): BUG=441581 118 // TODO(mcchou): BUG=441581
108 // Use SelectConfigurationCallback to return the agreed capabilities. 119 // Use SelectConfigurationCallback to return the agreed capabilities.
120 VLOG(1) << "Bluetooth audio sink: SelectConfiguration called";
121 callback.Run(options_.capabilities);
109 } 122 }
110 123
111 void BluetoothAudioSinkChromeOS::ClearConfiguration( 124 void BluetoothAudioSinkChromeOS::ClearConfiguration(
112 const dbus::ObjectPath& transport_path) { 125 const dbus::ObjectPath& transport_path) {
113 // TODO(mcchou): BUG=441581 126 // TODO(mcchou): BUG=441581
114 // Reset the configuration to the default one and close IOBuffer. 127 // Reset the configuration to the default one and close IOBuffer.
115 } 128 }
116 129
117 void BluetoothAudioSinkChromeOS::Release() { 130 void BluetoothAudioSinkChromeOS::Release() {
118 // TODO(mcchou): BUG=441581 131 VLOG(1) << "Bluetooth audio sink: Release called";
119 // Let the audio sink does the clean-up and do nothing here. 132 StateChanged(device::BluetoothAudioSink::STATE_INVALID);
120 } 133 }
121 134
122 void BluetoothAudioSinkChromeOS::Register( 135 void BluetoothAudioSinkChromeOS::Register(
123 const device::BluetoothAudioSink::Options& options, 136 const device::BluetoothAudioSink::Options& options,
124 const base::Closure& callback, 137 const base::Closure& callback,
125 const device::BluetoothAudioSink::ErrorCallback& error_callback) { 138 const device::BluetoothAudioSink::ErrorCallback& error_callback) {
126 // TODO(mcchou): BUG=441581 139 // TODO(mcchou): BUG=441581
127 // Get Media object, initiate an Media Endpoint with options, and return the 140 // Get Media object, initiate an Media Endpoint with options, and return the
128 // audio sink via callback. Add the audio sink as observer of both Media and 141 // audio sink via callback. Add the audio sink as observer of both Media and
129 // Media Transport. 142 // Media Transport.
143 DCHECK(adapter_.get());
144 DCHECK_EQ(state_, device::BluetoothAudioSink::STATE_DISCONNECTED);
145
146 // Gets system bus.
147 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
148
149 // Creates a Media Endpoint with newly-generated path.
150 endpoint_path_ = GenerateEndpointPath();
151 media_endpoint_.reset(
152 BluetoothMediaEndpointServiceProvider::Create(
153 system_bus, endpoint_path_, this));
154
155 DCHECK(media_endpoint_.get());
156
157 // Creates endpoint properties with |options|.
158 options_ = options;
159 chromeos::BluetoothMediaClient::EndpointProperties endpoint_properties;
160 endpoint_properties.uuid = std::string(
armansito 2015/01/29 04:22:56 std::string() shouldn't be necessary afaik
Miao 2015/01/29 23:58:38 Done.
161 BluetoothMediaClient::kBluetoothAudioSinkUUID);
162 endpoint_properties.codec = options_.codec;
163 endpoint_properties.capabilities = options_.capabilities;
164
165 // Gets Media object exported by D-Bus and registers the endpoint.
166 chromeos::BluetoothMediaClient* media =
167 DBusThreadManager::Get()->GetBluetoothMediaClient();
168 media->AddObserver(this);
169 media_path_ = adapter_->object_path();
170 media->RegisterEndpoint(
171 media_path_,
172 endpoint_path_,
173 endpoint_properties,
174 base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterSucceeded,
175 weak_ptr_factory_.GetWeakPtr(), callback),
176 base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterFailed,
177 weak_ptr_factory_.GetWeakPtr(), error_callback));
130 } 178 }
131 179
132 void BluetoothAudioSinkChromeOS::Unregister( 180 void BluetoothAudioSinkChromeOS::Unregister(
133 const base::Closure& callback, 181 const base::Closure& callback,
134 const device::BluetoothAudioSink::ErrorCallback& error_callback) { 182 const device::BluetoothAudioSink::ErrorCallback& error_callback) {
135 // TODO(mcchou): BUG=441581 183 // TODO(mcchou): BUG=441581
136 // Clean |observers_| and |transport_path_| and reset |state_| and |volume_|. 184 // Call UnregisterEndpoint on the media object with |media_path_| and clean
185 // |observers_| and transport_path_ and reset state_ and volume.
186 // Check whether the media endpoint is registered before invoking
187 // UnregisterEndpoint.
137 } 188 }
138 189
139 void BluetoothAudioSinkChromeOS::StateChanged( 190 void BluetoothAudioSinkChromeOS::StateChanged(
140 device::BluetoothAudioSink::State state) { 191 device::BluetoothAudioSink::State state) {
141 DCHECK_NE(state, state_); 192 if (state == state_)
193 return;
194
142 VLOG(1) << "Bluetooth audio sink state changed: " << state; 195 VLOG(1) << "Bluetooth audio sink state changed: " << state;
196
197 switch (state) {
198 case device::BluetoothAudioSink::STATE_INVALID: {
199 // TODO(mcchou): BUG=441581
200 // Clean media, media transport and media endpoint.
201 break;
202 }
203 case device::BluetoothAudioSink::STATE_DISCONNECTED: {
204 // TODO(mcchou): BUG=441581
205 // Clean media transport.
206 break;
207 }
208 case device::BluetoothAudioSink::STATE_IDLE: {
209 // TODO(mcchou): BUG=441581
210 // Triggered by MediaTransportPropertyChanged. Stop watching on file
211 // descriptor if there is one.
212 break;
213 }
214 case device::BluetoothAudioSink::STATE_PENDING: {
215 // TODO(mcchou): BUG=441581
216 // Call BluetoothMediaTransportClient::Acquire() to get fd and mtus.
217 break;
218 }
219 case device::BluetoothAudioSink::STATE_ACTIVE: {
220 // TODO(mcchou): BUG=441581
221 // Read from fd and call DataAvailable.
222 ReadFromFD();
223 break;
224 }
225 default:
226 break;
227 }
228
143 state_ = state; 229 state_ = state;
144 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, 230 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_,
145 BluetoothAudioSinkStateChanged(this, state_)); 231 BluetoothAudioSinkStateChanged(this, state_));
146 } 232 }
147 233
148 void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) { 234 void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) {
149 DCHECK_NE(volume, volume_); 235 DCHECK_NE(volume, volume_);
150 VLOG(1) << "Bluetooth audio sink volume changed: " << volume; 236 VLOG(1) << "Bluetooth audio sink volume changed: " << volume;
151 volume_ = volume; 237 volume_ = volume;
152 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, 238 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_,
153 BluetoothAudioSinkVolumeChanged(this, volume_)); 239 BluetoothAudioSinkVolumeChanged(this, volume_));
154 } 240 }
155 241
242 void BluetoothAudioSinkChromeOS::OnRegisterSucceeded(
243 const base::Closure& callback) {
244 VLOG(1) << "Bluetooth audio sink registerd";
245
246 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED);
247 callback.Run();
248 }
249
250 void BluetoothAudioSinkChromeOS::OnRegisterFailed(
251 const BluetoothAudioSink::ErrorCallback& error_callback,
252 const std::string& error_name,
253 const std::string& error_message) {
254 DCHECK(media_endpoint_.get());
255 VLOG(1) << "Bluetooth audio sink: " << error_name << ": " << error_message;
256
257 endpoint_path_ = dbus::ObjectPath("");
258 media_endpoint_ = nullptr;
armansito 2015/01/29 04:22:55 Nice, this deletes the existing BluetoothMediaEndp
Miao 2015/01/29 23:58:38 // operator=. Allows assignment from a nullptr. D
259 error_callback.Run(device::BluetoothAudioSink::ERROR_NOT_REGISTERED);
260 }
261
156 void BluetoothAudioSinkChromeOS::ReadFromFD() { 262 void BluetoothAudioSinkChromeOS::ReadFromFD() {
157 DCHECK_GE(fd_.value(), 0); 263 DCHECK_GE(fd_.value(), 0);
158 264
159 // TODO(mcchou): BUG=441581 265 // TODO(mcchou): BUG=441581
160 // Read from file descriptor using watcher and create a buffer to contain the 266 // Read from file descriptor using watcher and create a buffer to contain the
161 // data. Notify |Observers_| while there is audio data available. 267 // data. Notify |Observers_| while there is audio data available.
162 } 268 }
163 269
164 } // namespace chromeos 270 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698