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

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"
19 #include "dbus/file_descriptor.h"
16 20
17 using dbus::ObjectPath; 21 using dbus::ObjectPath;
18 22
19 namespace { 23 namespace {
20 24
21 // TODO(mcchou): Remove this constants once it is in cros_system_api. 25 // TODO(mcchou): Remove this constants once it is in cros_system_api.
22 const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1"; 26 const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1";
23 const char kNotImplemented[] = "org.bluez.NotImplemented"; 27 const char kNotImplemented[] = "org.bluez.NotImplemented";
28 const char kNotAuthorized[] = "org.bluez.NotAuthorized";
29 const char kFailed[] = "org.bluez.Failed";
30 const char kNotAvailable[] = "org.bluez.NotAvailable";
31
32 const int kInvalidFd = -1;
33 const uint16_t kReadMtu = 20;
34 const uint16_t kWriteMtu = 25;
24 35
25 ObjectPath GenerateTransportPath() { 36 ObjectPath GenerateTransportPath() {
26 static unsigned int sequence_number = 0; 37 static unsigned int sequence_number = 0;
27 ++sequence_number; 38 ++sequence_number;
28 std::stringstream path; 39 std::stringstream path;
29 path << chromeos::FakeBluetoothAdapterClient::kAdapterPath 40 path << chromeos::FakeBluetoothAdapterClient::kAdapterPath
30 << chromeos::FakeBluetoothMediaTransportClient::kTransportDevicePath 41 << chromeos::FakeBluetoothMediaTransportClient::kTransportDevicePath
31 << "/fd" << sequence_number; 42 << "/fd" << sequence_number;
32 return ObjectPath(path.str()); 43 return ObjectPath(path.str());
33 } 44 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 properties.reset(transport_properties); 93 properties.reset(transport_properties);
83 } 94 }
84 95
85 FakeBluetoothMediaTransportClient::Transport::~Transport() { 96 FakeBluetoothMediaTransportClient::Transport::~Transport() {
86 } 97 }
87 98
88 FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() { 99 FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() {
89 } 100 }
90 101
91 FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() { 102 FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() {
92 for (auto& it : endpoint_to_transport_map_) 103 STLDeleteValues(&endpoint_to_transport_map_);
93 delete it.second;
94 endpoint_to_transport_map_.clear();
95 } 104 }
96 105
97 // DBusClient override. 106 // DBusClient override.
98 void FakeBluetoothMediaTransportClient::Init(dbus::Bus* bus) { 107 void FakeBluetoothMediaTransportClient::Init(dbus::Bus* bus) {
99 } 108 }
100 109
101 void FakeBluetoothMediaTransportClient::AddObserver( 110 void FakeBluetoothMediaTransportClient::AddObserver(
102 BluetoothMediaTransportClient::Observer* observer) { 111 BluetoothMediaTransportClient::Observer* observer) {
103 observers_.AddObserver(observer); 112 observers_.AddObserver(observer);
104 } 113 }
105 114
106 void FakeBluetoothMediaTransportClient::RemoveObserver( 115 void FakeBluetoothMediaTransportClient::RemoveObserver(
107 BluetoothMediaTransportClient::Observer* observer) { 116 BluetoothMediaTransportClient::Observer* observer) {
108 observers_.RemoveObserver(observer); 117 observers_.RemoveObserver(observer);
109 } 118 }
110 119
111 FakeBluetoothMediaTransportClient::Properties* 120 FakeBluetoothMediaTransportClient::Properties*
112 FakeBluetoothMediaTransportClient::GetProperties( 121 FakeBluetoothMediaTransportClient::GetProperties(
113 const ObjectPath& object_path) { 122 const ObjectPath& object_path) {
114 ObjectPath endpoint_path = GetEndpointPath(object_path); 123 const ObjectPath& endpoint_path = GetEndpointPath(object_path);
115 if (!endpoint_path.IsValid() || 124 Transport* transport = GetTransport(endpoint_path);
116 !ContainsKey(endpoint_to_transport_map_, endpoint_path)) 125 if (!transport)
117 return nullptr; 126 return nullptr;
118 return endpoint_to_transport_map_[endpoint_path]->properties.get(); 127 return transport->properties.get();
119 } 128 }
120 129
121 void FakeBluetoothMediaTransportClient::Acquire( 130 void FakeBluetoothMediaTransportClient::Acquire(
122 const ObjectPath& object_path, 131 const ObjectPath& object_path,
123 const AcquireCallback& callback, 132 const AcquireCallback& callback,
124 const ErrorCallback& error_callback) { 133 const ErrorCallback& error_callback) {
125 error_callback.Run(kNotImplemented, ""); 134 VLOG(1) << "Acquire - transport path: " << object_path.value();
135 AcquireInternal(false, object_path, callback, error_callback);
126 } 136 }
127 137
128 void FakeBluetoothMediaTransportClient::TryAcquire( 138 void FakeBluetoothMediaTransportClient::TryAcquire(
129 const ObjectPath& object_path, 139 const ObjectPath& object_path,
130 const AcquireCallback& callback, 140 const AcquireCallback& callback,
131 const ErrorCallback& error_callback) { 141 const ErrorCallback& error_callback) {
132 error_callback.Run(kNotImplemented, ""); 142 VLOG(1) << "TryAcquire - transport path: " << object_path.value();
143 AcquireInternal(true, object_path, callback, error_callback);
133 } 144 }
134 145
135 void FakeBluetoothMediaTransportClient::Release( 146 void FakeBluetoothMediaTransportClient::Release(
136 const ObjectPath& object_path, 147 const ObjectPath& object_path,
137 const base::Closure& callback, 148 const base::Closure& callback,
138 const ErrorCallback& error_callback) { 149 const ErrorCallback& error_callback) {
139 error_callback.Run(kNotImplemented, ""); 150 error_callback.Run(kNotImplemented, "");
140 } 151 }
141 152
142 void FakeBluetoothMediaTransportClient::SetValid( 153 void FakeBluetoothMediaTransportClient::SetValid(
(...skipping 24 matching lines...) Expand all
167 properties->state.ReplaceValue(BluetoothMediaTransportClient::kStateIdle); 178 properties->state.ReplaceValue(BluetoothMediaTransportClient::kStateIdle);
168 properties->delay.ReplaceValue(kTransportDelay); 179 properties->delay.ReplaceValue(kTransportDelay);
169 properties->volume.ReplaceValue(kTransportVolume); 180 properties->volume.ReplaceValue(kTransportVolume);
170 181
171 endpoint_to_transport_map_[endpoint_path] = 182 endpoint_to_transport_map_[endpoint_path] =
172 new Transport(transport_path, properties.release()); 183 new Transport(transport_path, properties.release());
173 transport_to_endpoint_map_[transport_path] = endpoint_path; 184 transport_to_endpoint_map_[transport_path] = endpoint_path;
174 return; 185 return;
175 } 186 }
176 187
177 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 188 Transport* transport = GetTransport(endpoint_path);
189 if (!transport)
178 return; 190 return;
191 ObjectPath transport_path = transport->path;
179 192
180 // Notifies observers about the state change of the transport. 193 // Notifies observers about the state change of the transport.
181 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 194 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
182 MediaTransportRemoved(GetTransportPath(endpoint_path))); 195 MediaTransportRemoved(transport_path));
183 196
184 endpoint->ClearConfiguration(GetTransportPath(endpoint_path)); 197 endpoint->ClearConfiguration(transport_path);
185 transport_to_endpoint_map_.erase(GetTransportPath(endpoint_path)); 198 delete transport;
186 delete endpoint_to_transport_map_[endpoint_path];
187 endpoint_to_transport_map_.erase(endpoint_path); 199 endpoint_to_transport_map_.erase(endpoint_path);
200 transport_to_endpoint_map_.erase(transport_path);
188 } 201 }
189 202
190 void FakeBluetoothMediaTransportClient::SetState( 203 void FakeBluetoothMediaTransportClient::SetState(
191 const dbus::ObjectPath& endpoint_path, 204 const ObjectPath& endpoint_path,
192 const std::string& state) { 205 const std::string& state) {
193 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 206 VLOG(1) << "SetState - state: " << state;
207
208 Transport* transport = GetTransport(endpoint_path);
209 if (!transport)
194 return; 210 return;
195 211
196 endpoint_to_transport_map_[endpoint_path] 212 transport->properties->state.ReplaceValue(state);
197 ->properties->state.ReplaceValue(state);
198 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 213 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
199 MediaTransportPropertyChanged( 214 MediaTransportPropertyChanged(
200 GetTransportPath(endpoint_path), 215 transport->path,
201 BluetoothMediaTransportClient::kStateProperty)); 216 BluetoothMediaTransportClient::kStateProperty));
202 } 217 }
203 218
204 void FakeBluetoothMediaTransportClient::SetVolume( 219 void FakeBluetoothMediaTransportClient::SetVolume(
205 const dbus::ObjectPath& endpoint_path, 220 const ObjectPath& endpoint_path,
206 const uint16_t& volume) { 221 const uint16_t& volume) {
207 if (!ContainsKey(endpoint_to_transport_map_, endpoint_path)) 222 Transport* transport = GetTransport(endpoint_path);
223 if (!transport)
208 return; 224 return;
209 225
210 endpoint_to_transport_map_[endpoint_path]->properties->volume.ReplaceValue( 226 transport->properties->volume.ReplaceValue(volume);
211 volume);
212 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, 227 FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_,
213 MediaTransportPropertyChanged( 228 MediaTransportPropertyChanged(
214 GetTransportPath(endpoint_path), 229 transport->path,
215 BluetoothMediaTransportClient::kVolumeProperty)); 230 BluetoothMediaTransportClient::kVolumeProperty));
216 } 231 }
217 232
233 void FakeBluetoothMediaTransportClient::WriteData(
234 const ObjectPath& endpoint_path, const std::vector<char>& bytes) {
235 VLOG(1) << "WriteData - write " << bytes.size() << " bytes";
236
237 Transport* transport = GetTransport(endpoint_path);
238
239 if (!transport || transport->properties->state.value() != "active") {
240 VLOG(1) << "WriteData - write operation rejected, since the state isn't "
241 "active for endpoint: " << endpoint_path.value();
242 return;
243 }
244
245 if (!transport->input_fd.get()) {
246 VLOG(1) << "WriteData - invalid input file descriptor";
247 return;
248 }
249
250 ssize_t written_len =
251 write(transport->input_fd->GetPlatformFile(), bytes.data(), bytes.size());
252 if (written_len < 0) {
253 VLOG(1) << "WriteData - failed to write to the socket";
254 return;
255 }
256
257 VLOG(1) << "WriteData - wrote " << written_len << " bytes to the socket";
258 }
259
218 ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath( 260 ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath(
219 const ObjectPath& endpoint_path) { 261 const ObjectPath& endpoint_path) {
220 if (ContainsKey(endpoint_to_transport_map_, endpoint_path)) 262 Transport* transport = GetTransport(endpoint_path);
221 return endpoint_to_transport_map_[endpoint_path]->path; 263 return transport ? transport->path : ObjectPath("");
222 return ObjectPath("");
223 }
224
225 ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath(
226 const ObjectPath& transport_path) {
227 if (ContainsKey(transport_to_endpoint_map_, transport_path))
228 return transport_to_endpoint_map_[transport_path];
229 return ObjectPath("");
230 } 264 }
231 265
232 void FakeBluetoothMediaTransportClient::OnPropertyChanged( 266 void FakeBluetoothMediaTransportClient::OnPropertyChanged(
233 const std::string& property_name) { 267 const std::string& property_name) {
234 VLOG(1) << "Property " << property_name << " changed"; 268 VLOG(1) << "Property " << property_name << " changed";
235 } 269 }
236 270
271 ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath(
272 const ObjectPath& transport_path) {
273 const auto& it = transport_to_endpoint_map_.find(transport_path);
274 return it != transport_to_endpoint_map_.end() ? it->second : ObjectPath("");
275 }
276
277 FakeBluetoothMediaTransportClient::Transport*
278 FakeBluetoothMediaTransportClient::GetTransport(
279 const ObjectPath& endpoint_path) {
280 const auto& it = endpoint_to_transport_map_.find(endpoint_path);
281 return (it != endpoint_to_transport_map_.end()) ? it->second : nullptr;
282 }
283
284 FakeBluetoothMediaTransportClient::Transport*
285 FakeBluetoothMediaTransportClient::GetTransportByPath(
286 const dbus::ObjectPath& transport_path) {
287 return GetTransport(GetEndpointPath(transport_path));
288 }
289
290 void FakeBluetoothMediaTransportClient::AcquireInternal(
291 bool try_flag,
292 const ObjectPath& object_path,
293 const AcquireCallback& callback,
294 const ErrorCallback& error_callback) {
295 const ObjectPath& endpoint_path = GetEndpointPath(object_path);
296 Transport* transport = GetTransport(endpoint_path);
297 if (!transport) {
298 error_callback.Run(kFailed, "");
299 return;
300 }
301
302 std::string state = transport->properties->state.value();
303 if (state == "active") {
304 error_callback.Run(kNotAuthorized, "");
305 return;
306 }
307 if (state != "pending") {
308 error_callback.Run(try_flag ? kNotAvailable : kFailed, "");
309 return;
310 }
311
312 int fds[2];
313 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
314 transport->input_fd.reset();
315 error_callback.Run(kFailed, "");
316 return;
317 }
318 DCHECK((fds[0] > kInvalidFd) && (fds[1] > kInvalidFd));
319 transport->input_fd.reset(new base::File(fds[0]));
320
321 dbus::FileDescriptor out_fd(fds[1]);
322 callback.Run(&out_fd, kReadMtu, kWriteMtu);
323 SetState(endpoint_path, "active");
324 }
325
237 } // namespace chromeos 326 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/dbus/fake_bluetooth_media_transport_client.h ('k') | device/bluetooth/bluetooth_audio_sink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698