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

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

Issue 939753004: device/bluetooth: Implement Unregister() of BlueotoothAudioSinkChromeOS and disconnection-related c… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 #include <vector> 8 #include <vector>
9 9
10 #include "base/debug/stack_trace.h" 10 #include "base/debug/stack_trace.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "chromeos/dbus/dbus_thread_manager.h" 12 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "dbus/message.h" 13 #include "dbus/message.h"
14 #include "device/bluetooth/bluetooth_adapter_chromeos.h" 14 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
15 15
16 using dbus::ObjectPath;
17 using device::BluetoothAudioSink;
18
16 namespace { 19 namespace {
17 20
18 // TODO(mcchou): Add the constant to dbus/service_constants.h. 21 // TODO(mcchou): Add the constant to dbus/service_constants.h.
19 const char kBluetoothAudioSinkServicePath[] = "/org/chromium/AudioSink"; 22 const char kBluetoothAudioSinkServicePath[] = "/org/chromium/AudioSink";
20 23
21 dbus::ObjectPath GenerateEndpointPath() { 24 ObjectPath GenerateEndpointPath() {
22 static unsigned int sequence_number = 0; 25 static unsigned int sequence_number = 0;
23 ++sequence_number; 26 ++sequence_number;
24 std::stringstream path; 27 std::stringstream path;
25 path << kBluetoothAudioSinkServicePath << "/endpoint" << sequence_number; 28 path << kBluetoothAudioSinkServicePath << "/endpoint" << sequence_number;
26 return dbus::ObjectPath(path.str()); 29 return ObjectPath(path.str());
27 } 30 }
28 31
29 } // namespace 32 } // namespace
30 33
31 namespace chromeos { 34 namespace chromeos {
32 35
33 BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS( 36 BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS(
34 scoped_refptr<device::BluetoothAdapter> adapter) 37 scoped_refptr<device::BluetoothAdapter> adapter)
35 : state_(device::BluetoothAudioSink::STATE_INVALID), 38 : state_(BluetoothAudioSink::STATE_INVALID),
36 volume_(0), 39 volume_(nullptr),
Ben Chan 2015/02/19 00:21:45 no need to initialize scoped_ptr to nullptr what'
Miao 2015/02/23 21:04:25 Removed.
37 read_mtu_(0), 40 read_mtu_(nullptr),
38 write_mtu_(0), 41 write_mtu_(nullptr),
39 adapter_(adapter), 42 adapter_(adapter),
40 weak_ptr_factory_(this) { 43 weak_ptr_factory_(this) {
41 DCHECK(adapter_.get()); 44 DCHECK(adapter_.get());
42 DCHECK(adapter_->IsPresent()); 45 DCHECK(adapter_->IsPresent());
43 46
44 adapter_->AddObserver(this); 47 adapter_->AddObserver(this);
45 48
46 chromeos::BluetoothMediaClient* media = 49 chromeos::BluetoothMediaClient* media =
47 DBusThreadManager::Get()->GetBluetoothMediaClient(); 50 DBusThreadManager::Get()->GetBluetoothMediaClient();
48 DCHECK(media); 51 DCHECK(media);
49 media->AddObserver(this); 52 media->AddObserver(this);
50 53
51 chromeos::BluetoothMediaTransportClient *transport = 54 chromeos::BluetoothMediaTransportClient *transport =
52 chromeos::DBusThreadManager::Get()->GetBluetoothMediaTransportClient(); 55 chromeos::DBusThreadManager::Get()->GetBluetoothMediaTransportClient();
53 DCHECK(transport); 56 DCHECK(transport);
54 transport->AddObserver(this); 57 transport->AddObserver(this);
55 58
56 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); 59 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED);
57 } 60 }
58 61
59 BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() { 62 BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() {
60 DCHECK(adapter_.get()); 63 DCHECK(adapter_.get());
64
65 if (state_ != BluetoothAudioSink::STATE_INVALID &&
66 media_endpoint_.get() != nullptr) {
armansito 2015/02/19 00:37:46 nit: No need to compare against nullptr, the point
Miao 2015/02/23 21:04:25 Done.
67 Unregister(base::Bind(&base::DoNothing));
68 }
69
61 adapter_->RemoveObserver(this); 70 adapter_->RemoveObserver(this);
62 71
63 chromeos::BluetoothMediaClient* media = 72 chromeos::BluetoothMediaClient* media =
64 DBusThreadManager::Get()->GetBluetoothMediaClient(); 73 DBusThreadManager::Get()->GetBluetoothMediaClient();
65 DCHECK(media); 74 DCHECK(media);
66 media->RemoveObserver(this); 75 media->RemoveObserver(this);
67 76
68 chromeos::BluetoothMediaTransportClient *transport = 77 chromeos::BluetoothMediaTransportClient *transport =
69 chromeos::DBusThreadManager::Get()->GetBluetoothMediaTransportClient(); 78 chromeos::DBusThreadManager::Get()->GetBluetoothMediaTransportClient();
70 DCHECK(transport); 79 DCHECK(transport);
71 transport->RemoveObserver(this); 80 transport->RemoveObserver(this);
72
73 // TODO(mcchou): BUG=441581
74 // Unregister() should be called while media and media endpoint are still
75 // valid.
76 } 81 }
77 82
78 void BluetoothAudioSinkChromeOS::Unregister( 83 void BluetoothAudioSinkChromeOS::Unregister(const base::Closure& callback) {
armansito 2015/02/19 00:37:46 Note that if BluetoothAudioSinkChromeOS outlives D
Miao 2015/02/23 21:04:24 Done.
79 const base::Closure& callback, 84 // Gets Media object exported by D-Bus and unregisters the endpoint.
80 const device::BluetoothAudioSink::ErrorCallback& error_callback) { 85 chromeos::BluetoothMediaClient* media =
81 // TODO(mcchou): BUG=441581 86 DBusThreadManager::Get()->GetBluetoothMediaClient();
82 // Call UnregisterEndpoint on the media object with |media_path_| and clean 87 DCHECK(media);
83 // |observers_| and transport_path_ and reset state_ and volume. 88
84 // Check whether the media endpoint is registered before invoking 89 media->UnregisterEndpoint(
85 // UnregisterEndpoint. 90 media_path_,
91 endpoint_path_,
92 base::Bind(&BluetoothAudioSinkChromeOS::OnUnregisterSucceeded,
93 weak_ptr_factory_.GetWeakPtr(), callback),
94 base::Bind(&BluetoothAudioSinkChromeOS::OnUnregisterFailed,
95 weak_ptr_factory_.GetWeakPtr()));
86 } 96 }
87 97
88 void BluetoothAudioSinkChromeOS::AddObserver( 98 void BluetoothAudioSinkChromeOS::AddObserver(
89 device::BluetoothAudioSink::Observer* observer) { 99 BluetoothAudioSink::Observer* observer) {
90 DCHECK(observer); 100 DCHECK(observer);
91 observers_.AddObserver(observer); 101 observers_.AddObserver(observer);
92 } 102 }
93 103
94 void BluetoothAudioSinkChromeOS::RemoveObserver( 104 void BluetoothAudioSinkChromeOS::RemoveObserver(
95 device::BluetoothAudioSink::Observer* observer) { 105 BluetoothAudioSink::Observer* observer) {
96 DCHECK(observer); 106 DCHECK(observer);
97 observers_.RemoveObserver(observer); 107 observers_.RemoveObserver(observer);
98 } 108 }
99 109
100 device::BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const { 110 BluetoothAudioSink::State BluetoothAudioSinkChromeOS::GetState() const {
101 return state_; 111 return state_;
102 } 112 }
103 113
104 uint16_t BluetoothAudioSinkChromeOS::GetVolume() const { 114 uint16_t BluetoothAudioSinkChromeOS::GetVolume() const {
105 return volume_; 115 return volume_.get() != nullptr ? *volume_ : 0;
armansito 2015/02/19 00:37:46 nit: no need for '!= nullptr'
Miao 2015/02/23 21:04:25 Done.
106 } 116 }
107 117
108 void BluetoothAudioSinkChromeOS::AdapterPresentChanged( 118 void BluetoothAudioSinkChromeOS::AdapterPresentChanged(
109 device::BluetoothAdapter* adapter, 119 device::BluetoothAdapter* adapter, bool present) {
110 bool present) {
111 VLOG(1) << "Bluetooth audio sink: Bluetooth adapter present changed: " 120 VLOG(1) << "Bluetooth audio sink: Bluetooth adapter present changed: "
112 << present; 121 << present;
113 122
114 if (adapter->IsPresent()) { 123 if (adapter->IsPresent()) {
115 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); 124 StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
116 } else { 125 } else {
117 StateChanged(device::BluetoothAudioSink::STATE_INVALID); 126 adapter_->RemoveObserver(this);
127 StateChanged(BluetoothAudioSink::STATE_INVALID);
118 } 128 }
119 } 129 }
120 130
121 void BluetoothAudioSinkChromeOS::MediaRemoved( 131 void BluetoothAudioSinkChromeOS::AdapterPoweredChanged(
122 const dbus::ObjectPath& object_path) { 132 device::BluetoothAdapter* adapter, bool powered) {
123 // TODO(mcchou): BUG=441581 133 VLOG(1) << "Bluetooth audio sink: Bluetooth adapter powered changed: "
124 // Changes |state_| to STATE_INVALID or STATE_DISCONNECTED? 134 << powered;
135
136 // Regardless of the new powered state, |state_| goes to STATE_DISCONNECTED.
137 // If false, the transport is closed, but the endpoint is still valid for use.
138 // If true, the previous transport has been deprecated, so the |state_| has to
139 // be disconnected before SetConfigruation is called.
140 if (state_ == BluetoothAudioSink::STATE_INVALID)
141 return;
142 StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
Ben Chan 2015/02/19 00:21:45 this may be simpler: if (state_ != BluetoothAud
Miao 2015/02/23 21:04:25 Done.
143 }
144
145 void BluetoothAudioSinkChromeOS::MediaRemoved(const ObjectPath& object_path) {
125 if (object_path == media_path_) { 146 if (object_path == media_path_) {
126 StateChanged(device::BluetoothAudioSink::STATE_INVALID); 147 StateChanged(BluetoothAudioSink::STATE_INVALID);
127 } 148 }
128 } 149 }
129 150
130 void BluetoothAudioSinkChromeOS::MediaTransportRemoved( 151 void BluetoothAudioSinkChromeOS::MediaTransportRemoved(
131 const dbus::ObjectPath& object_path) { 152 const ObjectPath& object_path) {
132 // Whenever powered of |adapter_| turns false while present stays true, media 153 // Whenever powered of |adapter_| turns false while present stays true, media
133 // transport object should be removed accordingly, and the state should be 154 // transport object should be removed accordingly, and the state should be
134 // changed to STATE_DISCONNECTED. 155 // changed to STATE_DISCONNECTED.
135 if (object_path == transport_path_) { 156 if (object_path == transport_path_) {
136 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); 157 StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
137 } 158 }
138 } 159 }
139 160
140 void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged( 161 void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged(
141 const dbus::ObjectPath& object_path, 162 const ObjectPath& object_path,
142 const std::string& property_name) { 163 const std::string& property_name) {
143 if (object_path != transport_path_) 164 if (object_path != transport_path_)
144 return; 165 return;
145 166
146 // Retrieves the property set of the transport object with |object_path|. 167 // Retrieves the property set of the transport object with |object_path|.
147 chromeos::BluetoothMediaTransportClient::Properties* properties = 168 chromeos::BluetoothMediaTransportClient::Properties* properties =
148 DBusThreadManager::Get() 169 DBusThreadManager::Get()
149 ->GetBluetoothMediaTransportClient() 170 ->GetBluetoothMediaTransportClient()
150 ->GetProperties(object_path); 171 ->GetProperties(object_path);
151 172
152 // Dispatches a property changed event to the corresponding handler. 173 // Dispatches a property changed event to the corresponding handler.
153 if (property_name == properties->state.name()) { 174 if (property_name == properties->state.name()) {
154 if (properties->state.value() == 175 if (properties->state.value() ==
155 BluetoothMediaTransportClient::kStateIdle) { 176 BluetoothMediaTransportClient::kStateIdle) {
156 StateChanged(device::BluetoothAudioSink::STATE_IDLE); 177 StateChanged(BluetoothAudioSink::STATE_IDLE);
157 } else if (properties->state.value() == 178 } else if (properties->state.value() ==
158 BluetoothMediaTransportClient::kStatePending) { 179 BluetoothMediaTransportClient::kStatePending) {
159 StateChanged(device::BluetoothAudioSink::STATE_PENDING); 180 StateChanged(BluetoothAudioSink::STATE_PENDING);
160 } else if (properties->state.value() == 181 } else if (properties->state.value() ==
161 BluetoothMediaTransportClient::kStateActive) { 182 BluetoothMediaTransportClient::kStateActive) {
162 StateChanged(device::BluetoothAudioSink::STATE_ACTIVE); 183 StateChanged(BluetoothAudioSink::STATE_ACTIVE);
163 } 184 }
164 } else if (property_name == properties->volume.name()) { 185 } else if (property_name == properties->volume.name()) {
165 VolumeChanged(properties->volume.value()); 186 VolumeChanged(properties->volume.value());
166 } else { 187 } else {
167 VLOG(1) << "Bluetooth audio sink: transport property " << property_name 188 VLOG(1) << "Bluetooth audio sink: transport property " << property_name
168 << " changed"; 189 << " changed";
169 } 190 }
170 } 191 }
171 192
172 void BluetoothAudioSinkChromeOS::SetConfiguration( 193 void BluetoothAudioSinkChromeOS::SetConfiguration(
173 const dbus::ObjectPath& transport_path, 194 const ObjectPath& transport_path,
174 const TransportProperties& properties) { 195 const TransportProperties& properties) {
175 VLOG(1) << "Bluetooth audio sink: SetConfiguration called"; 196 VLOG(1) << "Bluetooth audio sink: SetConfiguration called";
176 transport_path_ = transport_path; 197 transport_path_ = transport_path;
177 198
178 // The initial state for a connection should be "idle". 199 // The initial state for a connection should be "idle".
179 if (properties.state != BluetoothMediaTransportClient::kStateIdle) { 200 if (properties.state != BluetoothMediaTransportClient::kStateIdle) {
180 VLOG(1) << "Bluetooth Audio Sink: unexpected state " << properties.state; 201 VLOG(1) << "Bluetooth Audio Sink: unexpected state " << properties.state;
181 return; 202 return;
182 } 203 }
183 204
184 // Updates |volume_| if the volume level is provided in |properties|. 205 // Updates |volume_| if the volume level is provided in |properties|.
185 if (properties.volume.get() != nullptr) 206 if (properties.volume.get() != nullptr) {
armansito 2015/02/19 00:37:46 nit: no need for '!= nullptr'
Miao 2015/02/23 21:04:24 Done.
207 volume_.reset(new uint16_t());
Ben Chan 2015/02/19 00:21:45 this looks kinda weird as VolumeChanged does nothi
armansito 2015/02/19 00:37:46 Why not make this assignment from VolumeChanged in
Miao 2015/02/23 21:04:24 Removed the allocation of memory here. Let VolumeC
186 VolumeChanged(*properties.volume); 208 VolumeChanged(*properties.volume);
209 }
187 210
188 StateChanged(device::BluetoothAudioSink::STATE_IDLE); 211 StateChanged(BluetoothAudioSink::STATE_IDLE);
189 } 212 }
190 213
191 void BluetoothAudioSinkChromeOS::SelectConfiguration( 214 void BluetoothAudioSinkChromeOS::SelectConfiguration(
192 const std::vector<uint8_t>& capabilities, 215 const std::vector<uint8_t>& capabilities,
193 const SelectConfigurationCallback& callback) { 216 const SelectConfigurationCallback& callback) {
194 VLOG(1) << "Bluetooth audio sink: SelectConfiguration called"; 217 VLOG(1) << "Bluetooth audio sink: SelectConfiguration called";
195 callback.Run(options_.capabilities); 218 callback.Run(options_.capabilities);
196 } 219 }
197 220
198 void BluetoothAudioSinkChromeOS::ClearConfiguration( 221 void BluetoothAudioSinkChromeOS::ClearConfiguration(
199 const dbus::ObjectPath& transport_path) { 222 const ObjectPath& transport_path) {
223 if (transport_path != transport_path_)
224 return;
200 VLOG(1) << "Bluetooth audio sink: ClearConfiguration called"; 225 VLOG(1) << "Bluetooth audio sink: ClearConfiguration called";
201 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); 226 StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
202 } 227 }
203 228
204 void BluetoothAudioSinkChromeOS::Released() { 229 void BluetoothAudioSinkChromeOS::Released() {
205 VLOG(1) << "Bluetooth audio sink: Released called"; 230 VLOG(1) << "Bluetooth audio sink: Released called";
206 StateChanged(device::BluetoothAudioSink::STATE_INVALID); 231 StateChanged(BluetoothAudioSink::STATE_INVALID);
207 } 232 }
208 233
209 void BluetoothAudioSinkChromeOS::Register( 234 void BluetoothAudioSinkChromeOS::Register(
210 const device::BluetoothAudioSink::Options& options, 235 const BluetoothAudioSink::Options& options,
211 const base::Closure& callback, 236 const base::Closure& callback,
212 const device::BluetoothAudioSink::ErrorCallback& error_callback) { 237 const BluetoothAudioSink::ErrorCallback& error_callback) {
213 DCHECK(adapter_.get()); 238 DCHECK(adapter_.get());
214 DCHECK_EQ(state_, device::BluetoothAudioSink::STATE_DISCONNECTED); 239 DCHECK_EQ(state_, BluetoothAudioSink::STATE_DISCONNECTED);
215 240
216 // Gets system bus. 241 // Gets system bus.
217 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); 242 dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus();
218 243
219 // Creates a Media Endpoint with newly-generated path. 244 // Creates a Media Endpoint with newly-generated path.
220 endpoint_path_ = GenerateEndpointPath(); 245 endpoint_path_ = GenerateEndpointPath();
221 media_endpoint_.reset( 246 media_endpoint_.reset(
222 BluetoothMediaEndpointServiceProvider::Create( 247 BluetoothMediaEndpointServiceProvider::Create(
223 system_bus, endpoint_path_, this)); 248 system_bus, endpoint_path_, this));
224 249
(...skipping 21 matching lines...) Expand all
246 base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterFailed, 271 base::Bind(&BluetoothAudioSinkChromeOS::OnRegisterFailed,
247 weak_ptr_factory_.GetWeakPtr(), error_callback)); 272 weak_ptr_factory_.GetWeakPtr(), error_callback));
248 } 273 }
249 274
250 BluetoothMediaEndpointServiceProvider* 275 BluetoothMediaEndpointServiceProvider*
251 BluetoothAudioSinkChromeOS::GetEndpointServiceProvider() { 276 BluetoothAudioSinkChromeOS::GetEndpointServiceProvider() {
252 return media_endpoint_.get(); 277 return media_endpoint_.get();
253 } 278 }
254 279
255 void BluetoothAudioSinkChromeOS::StateChanged( 280 void BluetoothAudioSinkChromeOS::StateChanged(
256 device::BluetoothAudioSink::State state) { 281 BluetoothAudioSink::State state) {
257 if (state == state_) 282 if (state == state_)
258 return; 283 return;
259 284
260 VLOG(1) << "Bluetooth audio sink state changed: " << state; 285 VLOG(1) << "Bluetooth audio sink state changed: " << state;
286 switch (state) {
287 case BluetoothAudioSink::STATE_INVALID: {
armansito 2015/02/19 00:37:46 All of these added scopes are unnecessary. I would
Miao 2015/02/23 21:04:24 Done.
288 ResetMedia();
289 ResetEndpoint();
261 290
262 switch (state) { 291 // Skips unnecessary clean-up on transport object.
263 case device::BluetoothAudioSink::STATE_INVALID: { 292 if (state_ != BluetoothAudioSink::STATE_DISCONNECTED)
armansito 2015/02/19 00:37:46 Kind of unnecessary I think, I'd just make ResetTr
Miao 2015/02/23 21:04:24 Done.
264 // TODO(mcchou): BUG=441581 293 ResetTransport();
265 ResetMedia();
266 ResetTransport();
267 ResetEndpoint();
268 break; 294 break;
269 } 295 }
270 case device::BluetoothAudioSink::STATE_DISCONNECTED: { 296 case BluetoothAudioSink::STATE_DISCONNECTED: {
271 // TODO(mcchou): BUG=441581
272 // Clean media transport and remove the audio sink from its observer list.
273 ResetTransport(); 297 ResetTransport();
274 break; 298 break;
275 } 299 }
276 case device::BluetoothAudioSink::STATE_IDLE: { 300 case BluetoothAudioSink::STATE_IDLE: {
277 // TODO(mcchou): BUG=441581 301 // TODO(mcchou): BUG=441581
278 // Triggered by MediaTransportPropertyChanged and SetConfiguration. 302 // Triggered by MediaTransportPropertyChanged and SetConfiguration.
279 // Stop watching on file descriptor if there is one. 303 // Stop watching on file descriptor if there is one.
280 break; 304 break;
281 } 305 }
282 case device::BluetoothAudioSink::STATE_PENDING: { 306 case BluetoothAudioSink::STATE_PENDING: {
283 // TODO(mcchou): BUG=441581 307 // TODO(mcchou): BUG=441581
284 // Call BluetoothMediaTransportClient::Acquire() to get fd and mtus. 308 // Call BluetoothMediaTransportClient::Acquire() to get fd and mtus.
285 break; 309 break;
286 } 310 }
287 case device::BluetoothAudioSink::STATE_ACTIVE: { 311 case BluetoothAudioSink::STATE_ACTIVE: {
288 // TODO(mcchou): BUG=441581 312 // TODO(mcchou): BUG=441581
289 // Read from fd and call DataAvailable. 313 // Read from fd and call DataAvailable.
290 ReadFromFD(); 314 ReadFromFD();
291 break; 315 break;
292 } 316 }
293 default: 317 default:
294 break; 318 break;
295 } 319 }
296 320
297 state_ = state; 321 state_ = state;
298 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, 322 FOR_EACH_OBSERVER(BluetoothAudioSink::Observer, observers_,
299 BluetoothAudioSinkStateChanged(this, state_)); 323 BluetoothAudioSinkStateChanged(this, state_));
300 } 324 }
301 325
302 void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) { 326 void BluetoothAudioSinkChromeOS::VolumeChanged(uint16_t volume) {
303 DCHECK_NE(volume, volume_); 327 if (volume_.get() == nullptr)
armansito 2015/02/19 00:37:46 nit: if (!volume_.get()) That said, your code loo
Miao 2015/02/23 21:04:24 Removed.
328 return;
304 VLOG(1) << "Bluetooth audio sink volume changed: " << volume; 329 VLOG(1) << "Bluetooth audio sink volume changed: " << volume;
305 volume_ = volume; 330 volume_.reset(new uint16_t(volume));
306 FOR_EACH_OBSERVER(device::BluetoothAudioSink::Observer, observers_, 331 FOR_EACH_OBSERVER(BluetoothAudioSink::Observer, observers_,
Miao 2015/02/23 21:04:24 Check whether the new volume before notifying obse
307 BluetoothAudioSinkVolumeChanged(this, volume_)); 332 BluetoothAudioSinkVolumeChanged(this, *volume_));
308 } 333 }
309 334
310 void BluetoothAudioSinkChromeOS::OnRegisterSucceeded( 335 void BluetoothAudioSinkChromeOS::OnRegisterSucceeded(
311 const base::Closure& callback) { 336 const base::Closure& callback) {
337 DCHECK(media_endpoint_.get());
312 VLOG(1) << "Bluetooth audio sink registerd"; 338 VLOG(1) << "Bluetooth audio sink registerd";
313 339
314 StateChanged(device::BluetoothAudioSink::STATE_DISCONNECTED); 340 StateChanged(BluetoothAudioSink::STATE_DISCONNECTED);
315 callback.Run(); 341 callback.Run();
316 } 342 }
317 343
318 void BluetoothAudioSinkChromeOS::OnRegisterFailed( 344 void BluetoothAudioSinkChromeOS::OnRegisterFailed(
319 const BluetoothAudioSink::ErrorCallback& error_callback, 345 const BluetoothAudioSink::ErrorCallback& error_callback,
320 const std::string& error_name, 346 const std::string& error_name,
321 const std::string& error_message) { 347 const std::string& error_message) {
322 DCHECK(media_endpoint_.get());
323 VLOG(1) << "Bluetooth audio sink: " << error_name << ": " << error_message; 348 VLOG(1) << "Bluetooth audio sink: " << error_name << ": " << error_message;
324 349
325 ResetEndpoint(); 350 ResetEndpoint();
326 error_callback.Run(device::BluetoothAudioSink::ERROR_NOT_REGISTERED); 351 error_callback.Run(BluetoothAudioSink::ERROR_NOT_REGISTERED);
352 }
353
354 void BluetoothAudioSinkChromeOS::OnUnregisterSucceeded(
355 const base::Closure& callback) {
356 VLOG(1) << "Bluetooth audio sink unregisterd";
357
358 // Once the state becomes STATE_INVALID, media, media transport and media
359 // endpoint will be reset.
360 StateChanged(BluetoothAudioSink::STATE_INVALID);
361 callback.Run();
362 }
363
364 void BluetoothAudioSinkChromeOS::OnUnregisterFailed(
365 const std::string& error_name,
366 const std::string& error_message) {
367 VLOG(1) << "Bluetooth audio sink: " << error_name << ": " << error_message;
327 } 368 }
328 369
329 void BluetoothAudioSinkChromeOS::ReadFromFD() { 370 void BluetoothAudioSinkChromeOS::ReadFromFD() {
330 DCHECK_GE(fd_.value(), 0); 371 DCHECK_GE(fd_.value(), 0);
331 372
332 // TODO(mcchou): BUG=441581 373 // TODO(mcchou): BUG=441581
333 // Read from file descriptor using watcher and create a buffer to contain the 374 // Read from file descriptor using watcher and create a buffer to contain the
334 // data. Notify |Observers_| while there is audio data available. 375 // data. Notify |Observers_| while there is audio data available.
335 } 376 }
336 377
337 void BluetoothAudioSinkChromeOS::ResetMedia() { 378 void BluetoothAudioSinkChromeOS::ResetMedia() {
338 media_path_ = dbus::ObjectPath(""); 379 media_path_ = dbus::ObjectPath("");
339 } 380 }
340 381
341 void BluetoothAudioSinkChromeOS::ResetTransport() { 382 void BluetoothAudioSinkChromeOS::ResetTransport() {
342 transport_path_ = dbus::ObjectPath(""); 383 transport_path_ = dbus::ObjectPath("");
384 VolumeChanged(0);
armansito 2015/02/19 00:37:46 So did volume just become 0 or are you cleaning up
Miao 2015/02/23 21:04:24 Once the transport is invalid, user applications s
343 volume_ = 0; 385 volume_ = 0;
Ben Chan 2015/02/19 00:21:45 volume_.reset()?
Miao 2015/02/23 21:04:24 Done.
344 read_mtu_ = 0; 386 read_mtu_ = 0;
345 write_mtu_ = 0; 387 write_mtu_ = 0;
346 fd_.PutValue(-1); 388 fd_.PutValue(-1);
347 } 389 }
348 390
349 void BluetoothAudioSinkChromeOS::ResetEndpoint() { 391 void BluetoothAudioSinkChromeOS::ResetEndpoint() {
350 endpoint_path_ = dbus::ObjectPath(""); 392 endpoint_path_ = ObjectPath("");
351 media_endpoint_ = nullptr; 393 media_endpoint_ = nullptr;
352 } 394 }
353 395
354 } // namespace chromeos 396 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698