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

Side by Side Diff: chromeos/dbus/fake_bluetooth_media_transport_client.cc

Issue 993273002: device/bluetooth: Add I/O watcher for audio data retrieval triggered by state change. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chromeos/dbus/fake_bluetooth_media_transport_client.h" 5 #include "chromeos/dbus/fake_bluetooth_media_transport_client.h"
6 6
7 #include <unistd.h>
8 #include <sys/socket.h>
9
7 #include <sstream> 10 #include <sstream>
8 11
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/stl_util.h" 13 #include "base/stl_util.h"
11 #include "chromeos/dbus/bluetooth_media_client.h" 14 #include "chromeos/dbus/bluetooth_media_client.h"
12 #include "chromeos/dbus/dbus_thread_manager.h" 15 #include "chromeos/dbus/dbus_thread_manager.h"
13 #include "chromeos/dbus/fake_bluetooth_adapter_client.h" 16 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
14 #include "chromeos/dbus/fake_bluetooth_media_client.h" 17 #include "chromeos/dbus/fake_bluetooth_media_client.h"
15 #include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h" 18 #include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h"
16 19
17 using dbus::ObjectPath; 20 using dbus::ObjectPath;
18 21
19 namespace { 22 namespace {
20 23
21 // TODO(mcchou): Remove this constants once it is in cros_system_api. 24 // TODO(mcchou): Remove this constants once it is in cros_system_api.
22 const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1"; 25 const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1";
23 const char kNotImplemented[] = "org.bluez.NotImplemented"; 26 const char kNotImplemented[] = "org.bluez.NotImplemented";
27 const char kNotAuthorized[] = "org.bluez.NotAuthorized";
28 const char kFailed[] = "org.bluez.Failed";
29 const char kNotAvailable[] = "org.bluez.NotAvailable";
30
31 const uint16_t kReadMtu = 20;
32 const uint16_t kWriteMtu = 25;
24 33
25 ObjectPath GenerateTransportPath() { 34 ObjectPath GenerateTransportPath() {
26 static unsigned int sequence_number = 0; 35 static unsigned int sequence_number = 0;
27 ++sequence_number; 36 ++sequence_number;
28 std::stringstream path; 37 std::stringstream path;
29 path << chromeos::FakeBluetoothAdapterClient::kAdapterPath 38 path << chromeos::FakeBluetoothAdapterClient::kAdapterPath
30 << chromeos::FakeBluetoothMediaTransportClient::kTransportDevicePath 39 << chromeos::FakeBluetoothMediaTransportClient::kTransportDevicePath
31 << "/fd" << sequence_number; 40 << "/fd" << sequence_number;
32 return ObjectPath(path.str()); 41 return ObjectPath(path.str());
33 } 42 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 properties.reset(transport_properties); 91 properties.reset(transport_properties);
83 } 92 }
84 93
85 FakeBluetoothMediaTransportClient::Transport::~Transport() { 94 FakeBluetoothMediaTransportClient::Transport::~Transport() {
86 } 95 }
87 96
88 FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() { 97 FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() {
89 } 98 }
90 99
91 FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() { 100 FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() {
92 for (auto& it : endpoint_to_transport_map_) 101 STLDeleteValues(&endpoint_to_transport_map_);
93 delete it.second;
94 endpoint_to_transport_map_.clear();
95 } 102 }
96 103
97 // DBusClient override. 104 // DBusClient override.
98 void FakeBluetoothMediaTransportClient::Init(dbus::Bus* bus) { 105 void FakeBluetoothMediaTransportClient::Init(dbus::Bus* bus) {
99 } 106 }
100 107
101 void FakeBluetoothMediaTransportClient::AddObserver( 108 void FakeBluetoothMediaTransportClient::AddObserver(
102 BluetoothMediaTransportClient::Observer* observer) { 109 BluetoothMediaTransportClient::Observer* observer) {
103 observers_.AddObserver(observer); 110 observers_.AddObserver(observer);
104 } 111 }
105 112
106 void FakeBluetoothMediaTransportClient::RemoveObserver( 113 void FakeBluetoothMediaTransportClient::RemoveObserver(
107 BluetoothMediaTransportClient::Observer* observer) { 114 BluetoothMediaTransportClient::Observer* observer) {
108 observers_.RemoveObserver(observer); 115 observers_.RemoveObserver(observer);
109 } 116 }
110 117
111 FakeBluetoothMediaTransportClient::Properties* 118 FakeBluetoothMediaTransportClient::Properties*
112 FakeBluetoothMediaTransportClient::GetProperties( 119 FakeBluetoothMediaTransportClient::GetProperties(
113 const ObjectPath& object_path) { 120 const ObjectPath& object_path) {
114 ObjectPath endpoint_path = GetEndpointPath(object_path); 121 ObjectPath endpoint_path = GetEndpointPath(object_path);
115 if (!endpoint_path.IsValid() || 122 Transport* transport = GetTransport(endpoint_path);
116 !ContainsKey(endpoint_to_transport_map_, endpoint_path)) 123 if (!transport)
117 return nullptr; 124 return nullptr;
118 return endpoint_to_transport_map_[endpoint_path]->properties.get(); 125 return transport->properties.get();
119 } 126 }
120 127
121 void FakeBluetoothMediaTransportClient::Acquire( 128 void FakeBluetoothMediaTransportClient::Acquire(
122 const ObjectPath& object_path, 129 const ObjectPath& object_path,
123 const AcquireCallback& callback, 130 const AcquireCallback& callback,
124 const ErrorCallback& error_callback) { 131 const ErrorCallback& error_callback) {
125 error_callback.Run(kNotImplemented, ""); 132 VLOG(1) << "Acquire - transport path: " << object_path.value();
133
134 ObjectPath endpoint_path = GetEndpointPath(object_path);
armansito 2015/03/12 03:42:54 const ObjectPath&
Miao 2015/03/12 22:33:31 Done.
135 Transport* transport = GetTransport(endpoint_path);
136 if (!transport) {
137 error_callback.Run(kFailed, "");
138 return;
139 }
140
141 std::string state = transport->properties->state.value();
142 if (state == "active") {
143 error_callback.Run(kNotAuthorized, "");
144 return;
145 }
146 if (state != "pending") {
147 error_callback.Run(kFailed, "");
148 return;
149 }
150
151 int fds[2];
152 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
153 transport->input_fd.reset();
154 error_callback.Run(kFailed, "");
155 return;
156 }
armansito 2015/03/12 03:42:54 Maybe add a DCHECK here that both fds[0] and fd[1]
Miao 2015/03/12 22:33:31 Done.
157 transport->input_fd.reset(new base::File(fds[0]));
158
159 callback.Run(fds[1], kReadMtu, kWriteMtu);
160 SetState(endpoint_path, "active");
126 } 161 }
127 162
128 void FakeBluetoothMediaTransportClient::TryAcquire( 163 void FakeBluetoothMediaTransportClient::TryAcquire(
129 const ObjectPath& object_path, 164 const ObjectPath& object_path,
130 const AcquireCallback& callback, 165 const AcquireCallback& callback,
131 const ErrorCallback& error_callback) { 166 const ErrorCallback& error_callback) {
132 error_callback.Run(kNotImplemented, ""); 167 VLOG(1) << "TryAcquire - transport path: " << object_path.value();
168
169 ObjectPath endpoint_path = GetEndpointPath(object_path);
armansito 2015/03/12 03:42:54 const ObjectPath&
Miao 2015/03/12 22:33:31 Done.
170 Transport* transport = GetTransport(endpoint_path);
armansito 2015/03/12 03:42:54 Maybe you want a helper like "GetTransportByPath"
171 if (!transport) {
172 error_callback.Run(kFailed, "");
173 return;
174 }
175
176 std::string state = transport->properties->state.value();
177 if (state == "active") {
178 error_callback.Run(kNotAuthorized, "");
179 return;
180 }
181
182 // NotAvailable error is an extra error type for TryAcquire.
183 if (state != "pending") {
184 error_callback.Run(kNotAvailable, "");
185 return;
186 }
187
188 int fds[2];
189 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
190 transport->input_fd.reset();
191 error_callback.Run(kFailed, "");
192 return;
193 }
194 transport->input_fd.reset(new base::File(fds[0]));
195
196 callback.Run(fds[1], kReadMtu, kWriteMtu);
197 SetState(endpoint_path, "active");
armansito 2015/03/12 03:42:54 A lot of the code between TryAcquire and Acquire i
Miao 2015/03/12 22:33:31 Acquire and TryAcquire have different error messag
armansito 2015/03/12 23:59:07 I don't think that's a good enough excuse to have
133 } 198 }
134 199
135 void FakeBluetoothMediaTransportClient::Release( 200 void FakeBluetoothMediaTransportClient::Release(
136 const ObjectPath& object_path, 201 const ObjectPath& object_path,
137 const base::Closure& callback, 202 const base::Closure& callback,
138 const ErrorCallback& error_callback) { 203 const ErrorCallback& error_callback) {
139 error_callback.Run(kNotImplemented, ""); 204 error_callback.Run(kNotImplemented, "");
140 } 205 }
141 206
142 void FakeBluetoothMediaTransportClient::SetValid( 207 void FakeBluetoothMediaTransportClient::SetValid(
(...skipping 24 matching lines...) Expand all
167 properties->state.ReplaceValue(BluetoothMediaTransportClient::kStateIdle); 232 properties->state.ReplaceValue(BluetoothMediaTransportClient::kStateIdle);
168 properties->delay.ReplaceValue(kTransportDelay); 233 properties->delay.ReplaceValue(kTransportDelay);
169 properties->volume.ReplaceValue(kTransportVolume); 234 properties->volume.ReplaceValue(kTransportVolume);
170 235
171 endpoint_to_transport_map_[endpoint_path] = 236 endpoint_to_transport_map_[endpoint_path] =
172 new Transport(transport_path, properties.release()); 237 new Transport(transport_path, properties.release());
173 transport_to_endpoint_map_[transport_path] = endpoint_path; 238 transport_to_endpoint_map_[transport_path] = endpoint_path;
174 return; 239 return;
175 } 240 }
176 241
177 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 242 Transport* transport = GetTransport(endpoint_path);
243 if (!transport)
178 return; 244 return;
armansito 2015/03/12 03:42:54 nit: new line after 'return'
245 ObjectPath transport_path = transport->path;
armansito 2015/03/12 03:42:54 const ObjectPath&
Miao 2015/03/12 22:33:31 Done.
179 246
180 // Notifies observers about the state change of the transport. 247 // Notifies observers about the state change of the transport.
181 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 248 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
182 MediaTransportRemoved(GetTransportPath(endpoint_path))); 249 MediaTransportRemoved(transport_path));
183 250
184 endpoint->ClearConfiguration(GetTransportPath(endpoint_path)); 251 endpoint->ClearConfiguration(transport_path);
185 transport_to_endpoint_map_.erase(GetTransportPath(endpoint_path)); 252 delete transport;
186 delete endpoint_to_transport_map_[endpoint_path];
187 endpoint_to_transport_map_.erase(endpoint_path); 253 endpoint_to_transport_map_.erase(endpoint_path);
254 transport_to_endpoint_map_.erase(transport_path);
188 } 255 }
189 256
190 void FakeBluetoothMediaTransportClient::SetState( 257 void FakeBluetoothMediaTransportClient::SetState(
191 const dbus::ObjectPath& endpoint_path, 258 const ObjectPath& endpoint_path,
192 const std::string& state) { 259 const std::string& state) {
193 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 260 VLOG(1) << "SetState - state: " << state;
261
262 Transport* transport = GetTransport(endpoint_path);
263 if (!transport)
194 return; 264 return;
195 265
196 endpoint_to_transport_map_[endpoint_path] 266 transport->properties->state.ReplaceValue(state);
197 ->properties->state.ReplaceValue(state);
198 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 267 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
199 MediaTransportPropertyChanged( 268 MediaTransportPropertyChanged(
200 GetTransportPath(endpoint_path), 269 transport->path,
201 BluetoothMediaTransportClient::kStateProperty)); 270 BluetoothMediaTransportClient::kStateProperty));
202 } 271 }
203 272
204 void FakeBluetoothMediaTransportClient::SetVolume( 273 void FakeBluetoothMediaTransportClient::SetVolume(
205 const dbus::ObjectPath& endpoint_path, 274 const ObjectPath& endpoint_path,
206 const uint16_t& volume) { 275 const uint16_t& volume) {
207 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 276 Transport* transport = GetTransport(endpoint_path);
277 if (!transport)
208 return; 278 return;
209 279
210 endpoint_to_transport_map_[endpoint_path]->properties->volume.ReplaceValue( 280 transport->properties->volume.ReplaceValue(volume);
211 volume);
212 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 281 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
213 MediaTransportPropertyChanged( 282 MediaTransportPropertyChanged(
214 GetTransportPath(endpoint_path), 283 transport->path,
215 BluetoothMediaTransportClient::kVolumeProperty)); 284 BluetoothMediaTransportClient::kVolumeProperty));
216 } 285 }
217 286
287 void FakeBluetoothMediaTransportClient::WriteData(
288 const ObjectPath& endpoint_path, const std::vector<char>& bytes) {
289 VLOG(1) << "WriteData";
armansito 2015/03/12 03:42:54 Maybe log the number of bytes here? Might be usefu
Miao 2015/03/12 22:33:31 Done.
290
291 Transport* transport = GetTransport(endpoint_path);
292
293 if (!transport || transport->properties->state.value() != "active") {
294 VLOG(1) << "WriteData - write operation rejected on endpoint: "
armansito 2015/03/12 03:42:54 You should probably log here that this was rejecte
Miao 2015/03/12 22:33:31 Done.
295 << endpoint_path.value();
296 return;
297 }
298
299 if (!transport->input_fd.get()) {
300 VLOG(1) << "WriteData - invalid file descriptors";
armansito 2015/03/12 03:42:54 nit: say "invalid input file descriptor"?
Miao 2015/03/12 22:33:31 Done.
301 return;
302 }
303
304 ssize_t written_len =
305 write(transport->input_fd->GetPlatformFile(), bytes.data(), bytes.size());
armansito 2015/03/12 03:42:54 I wonder if you should prevent sending more bytes
Miao 2015/03/12 22:33:31 I'll keep this for now.
armansito 2015/03/12 23:59:07 sgtm
306 if (written_len < 0) {
307 VLOG(1) << "WriteData - failed to write to the socket";
308 return;
309 }
310
311 VLOG(1) << "WriteData - wrote " << written_len << " bytes to the socket";
312 }
313
314 FakeBluetoothMediaTransportClient::Transport*
315 FakeBluetoothMediaTransportClient::GetTransport(
316 const ObjectPath& endpoint_path) {
317 auto it = endpoint_to_transport_map_.find(endpoint_path);
armansito 2015/03/12 03:42:54 const auto& it
Miao 2015/03/12 22:33:31 Done.
Miao 2015/03/12 22:33:31 Done.
318 return (it != endpoint_to_transport_map_.end()) ? it->second : nullptr;
319 }
320
321
218 ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath( 322 ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath(
219 const ObjectPath& endpoint_path) { 323 const ObjectPath& endpoint_path) {
220 if (ContainsKey(endpoint_to_transport_map_, endpoint_path)) 324 Transport* transport = GetTransport(endpoint_path);
221 return endpoint_to_transport_map_[endpoint_path]->path; 325 return transport ? transport->path : ObjectPath("");
222 return ObjectPath("");
223 } 326 }
224 327
225 ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath( 328 ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath(
226 const ObjectPath& transport_path) { 329 const ObjectPath& transport_path) {
227 if (ContainsKey(transport_to_endpoint_map_, transport_path)) 330 auto it = transport_to_endpoint_map_.find(transport_path);
armansito 2015/03/12 03:42:54 const auto& it
Miao 2015/03/12 22:33:31 Done.
228 return transport_to_endpoint_map_[transport_path]; 331 return it != transport_to_endpoint_map_.end() ? it->second : ObjectPath("");
229 return ObjectPath("");
230 } 332 }
231 333
232 void FakeBluetoothMediaTransportClient::OnPropertyChanged( 334 void FakeBluetoothMediaTransportClient::OnPropertyChanged(
233 const std::string& property_name) { 335 const std::string& property_name) {
234 VLOG(1) << "Property " << property_name << " changed"; 336 VLOG(1) << "Property " << property_name << " changed";
235 } 337 }
236 338
237 } // namespace chromeos 339 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698