OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chromeos/dbus/fake_bluetooth_device_client.h" | |
6 | |
7 #include <algorithm> | |
8 #include <map> | |
9 #include <string> | |
10 #include <utility> | |
11 #include <vector> | |
12 | |
13 #include "base/bind.h" | |
14 #include "base/logging.h" | |
15 #include "base/message_loop.h" | |
16 #include "base/stl_util.h" | |
17 #include "base/time.h" | |
18 #include "chromeos/dbus/dbus_thread_manager.h" | |
19 #include "chromeos/dbus/fake_bluetooth_adapter_client.h" | |
20 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" | |
21 #include "chromeos/dbus/fake_bluetooth_agent_service_provider.h" | |
22 #include "dbus/object_path.h" | |
23 #include "third_party/cros_system_api/dbus/service_constants.h" | |
24 | |
25 namespace { | |
26 | |
27 // Default interval between simulated events. | |
28 const int kSimulationIntervalMs = 750; | |
29 | |
30 } | |
31 | |
32 namespace chromeos { | |
33 | |
34 const char FakeBluetoothDeviceClient::kPairedDevicePath[] = | |
35 "/fake/hci0/dev0"; | |
36 const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] = | |
37 "00:11:22:33:44:55"; | |
38 const char FakeBluetoothDeviceClient::kPairedDeviceName[] = | |
39 "Fake Device"; | |
40 const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104; | |
41 | |
42 const char FakeBluetoothDeviceClient::kAppleMousePath[] = | |
43 "/fake/hci0/dev1"; | |
44 const char FakeBluetoothDeviceClient::kAppleMouseAddress[] = | |
45 "28:CF:DA:00:00:00"; | |
46 const char FakeBluetoothDeviceClient::kAppleMouseName[] = | |
47 "Apple Magic Mouse"; | |
48 const uint32 FakeBluetoothDeviceClient::kAppleMouseClass = 0x002580; | |
49 | |
50 const char FakeBluetoothDeviceClient::kAppleKeyboardPath[] = | |
51 "/fake/hci0/dev2"; | |
52 const char FakeBluetoothDeviceClient::kAppleKeyboardAddress[] = | |
53 "28:37:37:00:00:00"; | |
54 const char FakeBluetoothDeviceClient::kAppleKeyboardName[] = | |
55 "Apple Wireless Keyboard"; | |
56 const uint32 FakeBluetoothDeviceClient::kAppleKeyboardClass = 0x002540; | |
57 | |
58 const char FakeBluetoothDeviceClient::kVanishingDevicePath[] = | |
59 "/fake/hci0/dev3"; | |
60 const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] = | |
61 "01:02:03:04:05:06"; | |
62 const char FakeBluetoothDeviceClient::kVanishingDeviceName[] = | |
63 "Vanishing Device"; | |
64 const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104; | |
65 | |
66 const char FakeBluetoothDeviceClient::kMicrosoftMousePath[] = | |
67 "/fake/hci0/dev4"; | |
68 const char FakeBluetoothDeviceClient::kMicrosoftMouseAddress[] = | |
69 "7C:ED:8D:00:00:00"; | |
70 const char FakeBluetoothDeviceClient::kMicrosoftMouseName[] = | |
71 "Microsoft Mouse"; | |
72 const uint32 FakeBluetoothDeviceClient::kMicrosoftMouseClass = 0x002540; | |
73 | |
74 const char FakeBluetoothDeviceClient::kMotorolaKeyboardPath[] = | |
75 "/fake/hci0/dev5"; | |
76 const char FakeBluetoothDeviceClient::kMotorolaKeyboardAddress[] = | |
77 "00:0F:F6:00:00:00"; | |
78 const char FakeBluetoothDeviceClient::kMotorolaKeyboardName[] = | |
79 "Motorola Keyboard"; | |
80 const uint32 FakeBluetoothDeviceClient::kMotorolaKeyboardClass = 0x002580; | |
81 | |
82 const char FakeBluetoothDeviceClient::kSonyHeadphonesPath[] = | |
83 "/fake/hci0/dev6"; | |
84 const char FakeBluetoothDeviceClient::kSonyHeadphonesAddress[] = | |
85 "00:24:BE:00:00:00"; | |
86 const char FakeBluetoothDeviceClient::kSonyHeadphonesName[] = | |
87 "Sony BT-00"; | |
88 const uint32 FakeBluetoothDeviceClient::kSonyHeadphonesClass = 0x240408; | |
89 | |
90 const char FakeBluetoothDeviceClient::kPhonePath[] = | |
91 "/fake/hci0/dev7"; | |
92 const char FakeBluetoothDeviceClient::kPhoneAddress[] = | |
93 "20:7D:74:00:00:00"; | |
94 const char FakeBluetoothDeviceClient::kPhoneName[] = | |
95 "Phone"; | |
96 const uint32 FakeBluetoothDeviceClient::kPhoneClass = 0x7a020c; | |
97 | |
98 const char FakeBluetoothDeviceClient::kWeirdDevicePath[] = | |
99 "/fake/hci0/dev8"; | |
100 const char FakeBluetoothDeviceClient::kWeirdDeviceAddress[] = | |
101 "20:7D:74:00:00:01"; | |
102 const char FakeBluetoothDeviceClient::kWeirdDeviceName[] = | |
103 "Weird Device"; | |
104 const uint32 FakeBluetoothDeviceClient::kWeirdDeviceClass = 0x7a020c; | |
105 | |
106 FakeBluetoothDeviceClient::Properties::Properties( | |
107 const PropertyChangedCallback& callback) | |
108 : ExperimentalBluetoothDeviceClient::Properties( | |
109 NULL, | |
110 bluetooth_device::kExperimentalBluetoothDeviceInterface, | |
111 callback) { | |
112 } | |
113 | |
114 FakeBluetoothDeviceClient::Properties::~Properties() { | |
115 } | |
116 | |
117 void FakeBluetoothDeviceClient::Properties::Get( | |
118 dbus::PropertyBase* property, | |
119 dbus::PropertySet::GetCallback callback) { | |
120 VLOG(1) << "Get " << property->name(); | |
121 callback.Run(false); | |
122 } | |
123 | |
124 void FakeBluetoothDeviceClient::Properties::GetAll() { | |
125 VLOG(1) << "GetAll"; | |
126 } | |
127 | |
128 void FakeBluetoothDeviceClient::Properties::Set( | |
129 dbus::PropertyBase *property, | |
130 dbus::PropertySet::SetCallback callback) { | |
131 VLOG(1) << "Set " << property->name(); | |
132 if (property->name() == trusted.name()) { | |
133 callback.Run(true); | |
134 property->ReplaceValueWithSetValue(); | |
135 NotifyPropertyChanged(property->name()); | |
136 } else { | |
137 callback.Run(false); | |
138 } | |
139 } | |
140 | |
141 | |
142 FakeBluetoothDeviceClient::FakeBluetoothDeviceClient() | |
143 : simulation_interval_ms_(kSimulationIntervalMs), | |
144 discovery_simulation_step_(0), | |
145 pairing_cancelled_(false) { | |
146 Properties* properties = new Properties(base::Bind( | |
147 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
148 base::Unretained(this), | |
149 dbus::ObjectPath(kPairedDevicePath))); | |
150 properties->address.ReplaceValue(kPairedDeviceAddress); | |
151 properties->bluetooth_class.ReplaceValue(kPairedDeviceClass); | |
152 properties->name.ReplaceValue("Fake Device (Name)"); | |
153 properties->alias.ReplaceValue(kPairedDeviceName); | |
154 properties->paired.ReplaceValue(true); | |
155 properties->trusted.ReplaceValue(true); | |
156 properties->adapter.ReplaceValue( | |
157 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
158 | |
159 std::vector<std::string> uuids; | |
160 uuids.push_back("00001800-0000-1000-8000-00805f9b34fb"); | |
161 uuids.push_back("00001801-0000-1000-8000-00805f9b34fb"); | |
162 properties->uuids.ReplaceValue(uuids); | |
163 | |
164 properties_map_[dbus::ObjectPath(kPairedDevicePath)] = properties; | |
165 device_list_.push_back(dbus::ObjectPath(kPairedDevicePath)); | |
166 } | |
167 | |
168 FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() { | |
169 // Clean up Properties structures | |
170 STLDeleteValues(&properties_map_); | |
171 } | |
172 | |
173 void FakeBluetoothDeviceClient::AddObserver(Observer* observer) { | |
174 observers_.AddObserver(observer); | |
175 } | |
176 | |
177 void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) { | |
178 observers_.RemoveObserver(observer); | |
179 } | |
180 | |
181 std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter( | |
182 const dbus::ObjectPath& adapter_path) { | |
183 if (adapter_path == | |
184 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)) | |
185 return device_list_; | |
186 else | |
187 return std::vector<dbus::ObjectPath>(); | |
188 } | |
189 | |
190 FakeBluetoothDeviceClient::Properties* | |
191 FakeBluetoothDeviceClient::GetProperties(const dbus::ObjectPath& object_path) { | |
192 PropertiesMap::iterator iter = properties_map_.find(object_path); | |
193 if (iter != properties_map_.end()) | |
194 return iter->second; | |
195 return NULL; | |
196 } | |
197 | |
198 void FakeBluetoothDeviceClient::Connect( | |
199 const dbus::ObjectPath& object_path, | |
200 const base::Closure& callback, | |
201 const ErrorCallback& error_callback) { | |
202 VLOG(1) << "Connect: " << object_path.value(); | |
203 Properties* properties = GetProperties(object_path); | |
204 | |
205 if (properties->connected.value() == true) { | |
206 // Already connected. | |
207 callback.Run(); | |
208 return; | |
209 } | |
210 | |
211 if (properties->paired.value() != true && | |
212 object_path != dbus::ObjectPath(kMicrosoftMousePath)) { | |
213 // Must be paired. | |
214 error_callback.Run(bluetooth_adapter::kErrorFailed, "Not paired"); | |
215 return; | |
216 } else if (properties->paired.value() == true && | |
217 object_path == dbus::ObjectPath(kMicrosoftMousePath)) { | |
218 // Must not be paired | |
219 error_callback.Run(bluetooth_adapter::kErrorFailed, | |
220 "Connection fails while paired"); | |
221 return; | |
222 } | |
223 | |
224 // The device can be connected. | |
225 properties->connected.ReplaceValue(true); | |
226 | |
227 callback.Run(); | |
228 properties->NotifyPropertyChanged(properties->connected.name()); | |
229 } | |
230 | |
231 void FakeBluetoothDeviceClient::Disconnect( | |
232 const dbus::ObjectPath& object_path, | |
233 const base::Closure& callback, | |
234 const ErrorCallback& error_callback) { | |
235 VLOG(1) << "Disconnect: " << object_path.value(); | |
236 Properties* properties = GetProperties(object_path); | |
237 | |
238 if (properties->connected.value() == true) { | |
239 properties->connected.ReplaceValue(false); | |
240 | |
241 callback.Run(); | |
242 properties->NotifyPropertyChanged(properties->connected.name()); | |
243 } else { | |
244 error_callback.Run("org.bluez.Error.NotConnected", "Not Connected"); | |
245 } | |
246 } | |
247 | |
248 void FakeBluetoothDeviceClient::ConnectProfile( | |
249 const dbus::ObjectPath& object_path, | |
250 const std::string& uuid, | |
251 const base::Closure& callback, | |
252 const ErrorCallback& error_callback) { | |
253 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid; | |
254 error_callback.Run(kNoResponseError, ""); | |
255 } | |
256 | |
257 void FakeBluetoothDeviceClient::DisconnectProfile( | |
258 const dbus::ObjectPath& object_path, | |
259 const std::string& uuid, | |
260 const base::Closure& callback, | |
261 const ErrorCallback& error_callback) { | |
262 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid; | |
263 error_callback.Run(kNoResponseError, ""); | |
264 } | |
265 | |
266 void FakeBluetoothDeviceClient::Pair( | |
267 const dbus::ObjectPath& object_path, | |
268 const base::Closure& callback, | |
269 const ErrorCallback& error_callback) { | |
270 VLOG(1) << "Pair: " << object_path.value(); | |
271 Properties* properties = GetProperties(object_path); | |
272 | |
273 if (properties->paired.value() == true) { | |
274 // Already paired. | |
275 callback.Run(); | |
276 return; | |
277 } | |
278 | |
279 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = | |
280 static_cast<FakeBluetoothAgentManagerClient*>( | |
281 DBusThreadManager::Get()-> | |
282 GetExperimentalBluetoothAgentManagerClient()); | |
283 FakeBluetoothAgentServiceProvider* agent_service_provider = | |
284 fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); | |
285 if (agent_service_provider == NULL) { | |
286 error_callback.Run(kNoResponseError, "Missing agent"); | |
287 return; | |
288 } | |
289 | |
290 if (object_path == dbus::ObjectPath(kAppleMousePath) || | |
291 object_path == dbus::ObjectPath(kMicrosoftMousePath)) { | |
292 // No need to call anything on the pairing delegate, just wait 3 times | |
293 // the interval before acting as if the other end accepted it. | |
294 MessageLoop::current()->PostDelayedTask( | |
youngki
2013/04/17 16:23:45
I suggest we use base::SequencedTaskRunner instead
keybuk
2013/04/17 17:46:31
Do you have an example of this? No existing test c
| |
295 FROM_HERE, | |
296 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
297 base::Unretained(this), | |
298 object_path, callback, error_callback), | |
299 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); | |
300 | |
301 } else if (object_path == dbus::ObjectPath(kAppleKeyboardPath)) { | |
302 // Display a Pincode, and wait 7 times the interval before acting as | |
303 // if the other end accepted it. | |
304 agent_service_provider->DisplayPinCode(object_path, "123456"); | |
305 | |
306 MessageLoop::current()->PostDelayedTask( | |
307 FROM_HERE, | |
308 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
309 base::Unretained(this), | |
310 object_path, callback, error_callback), | |
311 base::TimeDelta::FromMilliseconds(7 * simulation_interval_ms_)); | |
312 | |
313 } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) { | |
314 // The vanishing device simulates being too far away, and thus times out. | |
315 MessageLoop::current()->PostDelayedTask( | |
316 FROM_HERE, | |
317 base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing, | |
318 base::Unretained(this), | |
319 object_path, error_callback), | |
320 base::TimeDelta::FromMilliseconds(4 * simulation_interval_ms_)); | |
321 | |
322 } else if (object_path == dbus::ObjectPath(kMotorolaKeyboardPath)) { | |
323 // Display a passkey, and each interval act as if another key was entered | |
324 // for it. | |
325 agent_service_provider->DisplayPasskey(object_path, 123456, 0); | |
326 | |
327 MessageLoop::current()->PostDelayedTask( | |
328 FROM_HERE, | |
329 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, | |
330 base::Unretained(this), | |
331 1, object_path, callback, error_callback), | |
332 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
333 | |
334 } else if (object_path == dbus::ObjectPath(kSonyHeadphonesPath)) { | |
335 // Request a Pincode. | |
336 agent_service_provider->RequestPinCode( | |
337 object_path, | |
338 base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback, | |
339 base::Unretained(this), | |
340 object_path, | |
341 callback, | |
342 error_callback)); | |
343 | |
344 } else if (object_path == dbus::ObjectPath(kPhonePath)) { | |
345 // Request confirmation of a Passkey. | |
346 agent_service_provider->RequestConfirmation( | |
347 object_path, 123456, | |
348 base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, | |
349 base::Unretained(this), | |
350 object_path, | |
351 callback, | |
352 error_callback)); | |
353 | |
354 } else if (object_path == dbus::ObjectPath(kWeirdDevicePath)) { | |
355 // Request a Passkey from the user. | |
356 agent_service_provider->RequestPasskey( | |
357 object_path, | |
358 base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback, | |
359 base::Unretained(this), | |
360 object_path, | |
361 callback, | |
362 error_callback)); | |
363 | |
364 } else { | |
365 error_callback.Run(kNoResponseError, "No pairing fake"); | |
366 } | |
367 } | |
368 | |
369 void FakeBluetoothDeviceClient::CancelPairing( | |
370 const dbus::ObjectPath& object_path, | |
371 const base::Closure& callback, | |
372 const ErrorCallback& error_callback) { | |
373 VLOG(1) << "CancelPairing: " << object_path.value(); | |
374 pairing_cancelled_ = true; | |
375 callback.Run(); | |
376 } | |
377 | |
378 | |
379 void FakeBluetoothDeviceClient::BeginDiscoverySimulation( | |
380 const dbus::ObjectPath& adapter_path) { | |
381 VLOG(1) << "starting discovery simulation"; | |
382 | |
383 discovery_simulation_step_ = 1; | |
384 | |
385 MessageLoop::current()->PostDelayedTask( | |
386 FROM_HERE, | |
387 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, | |
388 base::Unretained(this)), | |
389 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
390 } | |
391 | |
392 void FakeBluetoothDeviceClient::EndDiscoverySimulation( | |
393 const dbus::ObjectPath& adapter_path) { | |
394 VLOG(1) << "stopping discovery simulation"; | |
395 discovery_simulation_step_ = 0; | |
396 } | |
397 | |
398 void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) { | |
399 simulation_interval_ms_ = interval_ms; | |
400 } | |
401 | |
402 void FakeBluetoothDeviceClient::RemoveDevice( | |
403 const dbus::ObjectPath& adapter_path, | |
404 const dbus::ObjectPath& device_path) { | |
405 std::vector<dbus::ObjectPath>::iterator listiter = | |
406 std::find(device_list_.begin(), device_list_.end(), device_path); | |
407 if (listiter == device_list_.end()) | |
408 return; | |
409 | |
410 PropertiesMap::iterator iter = properties_map_.find(device_path); | |
411 Properties* properties = iter->second; | |
412 | |
413 VLOG(1) << "removing device: " << properties->alias.value(); | |
414 device_list_.erase(listiter); | |
415 | |
416 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
417 DeviceRemoved(device_path)); | |
418 | |
419 delete properties; | |
420 properties_map_.erase(iter); | |
421 } | |
422 | |
423 void FakeBluetoothDeviceClient::OnPropertyChanged( | |
424 const dbus::ObjectPath& object_path, | |
425 const std::string& property_name) { | |
426 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
427 DevicePropertyChanged(object_path, property_name)); | |
428 } | |
429 | |
430 void FakeBluetoothDeviceClient::DiscoverySimulationTimer() { | |
431 if (!discovery_simulation_step_) | |
432 return; | |
433 | |
434 // Timer fires every .75s, the numbers below are arbitrary to give a feel | |
435 // for a discovery process. | |
436 VLOG(1) << "discovery simulation, step " << discovery_simulation_step_; | |
437 if (discovery_simulation_step_ == 2) { | |
438 if (std::find(device_list_.begin(), device_list_.end(), | |
439 dbus::ObjectPath(kAppleMousePath)) == device_list_.end()) { | |
440 Properties* properties = new Properties(base::Bind( | |
441 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
442 base::Unretained(this), | |
443 dbus::ObjectPath(kAppleMousePath))); | |
444 properties->address.ReplaceValue(kAppleMouseAddress); | |
445 properties->bluetooth_class.ReplaceValue(kAppleMouseClass); | |
446 properties->name.ReplaceValue("Fake Apple Magic Mouse"); | |
447 properties->alias.ReplaceValue(kAppleMouseName); | |
448 properties->adapter.ReplaceValue( | |
449 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
450 | |
451 properties_map_[dbus::ObjectPath(kAppleMousePath)] = properties; | |
452 device_list_.push_back(dbus::ObjectPath(kAppleMousePath)); | |
453 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
454 DeviceAdded(dbus::ObjectPath(kAppleMousePath))); | |
455 } | |
456 | |
457 } else if (discovery_simulation_step_ == 4) { | |
458 if (std::find(device_list_.begin(), device_list_.end(), | |
459 dbus::ObjectPath(kAppleKeyboardPath)) == device_list_.end()) { | |
460 Properties *properties = new Properties(base::Bind( | |
461 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
462 base::Unretained(this), | |
463 dbus::ObjectPath(kAppleKeyboardPath))); | |
464 properties->address.ReplaceValue(kAppleKeyboardAddress); | |
465 properties->bluetooth_class.ReplaceValue(kAppleKeyboardClass); | |
466 properties->name.ReplaceValue("Fake Apple Wireless Keyboard"); | |
467 properties->alias.ReplaceValue(kAppleKeyboardName); | |
468 properties->adapter.ReplaceValue( | |
469 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
470 | |
471 properties_map_[dbus::ObjectPath(kAppleKeyboardPath)] = properties; | |
472 device_list_.push_back(dbus::ObjectPath(kAppleKeyboardPath)); | |
473 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
474 DeviceAdded(dbus::ObjectPath(kAppleKeyboardPath))); | |
475 } | |
476 | |
477 if (std::find(device_list_.begin(), device_list_.end(), | |
478 dbus::ObjectPath(kVanishingDevicePath)) == | |
479 device_list_.end()) { | |
480 Properties* properties = new Properties(base::Bind( | |
481 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
482 base::Unretained(this), | |
483 dbus::ObjectPath(kVanishingDevicePath))); | |
484 properties->address.ReplaceValue(kVanishingDeviceAddress); | |
485 properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass); | |
486 properties->name.ReplaceValue("Fake Vanishing Device"); | |
487 properties->alias.ReplaceValue(kVanishingDeviceName); | |
488 properties->adapter.ReplaceValue( | |
489 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
490 | |
491 properties_map_[dbus::ObjectPath(kVanishingDevicePath)] = properties; | |
492 device_list_.push_back(dbus::ObjectPath(kVanishingDevicePath)); | |
493 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
494 DeviceAdded(dbus::ObjectPath(kVanishingDevicePath))); | |
495 } | |
496 | |
497 } else if (discovery_simulation_step_ == 7) { | |
498 if (std::find(device_list_.begin(), device_list_.end(), | |
499 dbus::ObjectPath(kMicrosoftMousePath)) == | |
500 device_list_.end()) { | |
501 Properties* properties = new Properties(base::Bind( | |
502 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
503 base::Unretained(this), | |
504 dbus::ObjectPath(kMicrosoftMousePath))); | |
505 properties->address.ReplaceValue(kMicrosoftMouseAddress); | |
506 properties->bluetooth_class.ReplaceValue(kMicrosoftMouseClass); | |
507 properties->name.ReplaceValue("Fake Microsoft Mouse"); | |
508 properties->alias.ReplaceValue(kMicrosoftMouseName); | |
509 properties->adapter.ReplaceValue( | |
510 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
511 | |
512 properties_map_[dbus::ObjectPath(kMicrosoftMousePath)] = properties; | |
513 device_list_.push_back(dbus::ObjectPath(kMicrosoftMousePath)); | |
514 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
515 DeviceAdded(dbus::ObjectPath(kMicrosoftMousePath))); | |
516 } | |
517 | |
518 } else if (discovery_simulation_step_ == 8) { | |
519 if (std::find(device_list_.begin(), device_list_.end(), | |
520 dbus::ObjectPath(kMotorolaKeyboardPath)) == | |
521 device_list_.end()) { | |
522 Properties* properties = new Properties(base::Bind( | |
523 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
524 base::Unretained(this), | |
525 dbus::ObjectPath(kMotorolaKeyboardPath))); | |
526 properties->address.ReplaceValue(kMotorolaKeyboardAddress); | |
527 properties->bluetooth_class.ReplaceValue(kMotorolaKeyboardClass); | |
528 properties->name.ReplaceValue("Fake Motorola Keyboard"); | |
529 properties->alias.ReplaceValue(kMotorolaKeyboardName); | |
530 properties->adapter.ReplaceValue( | |
531 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
532 | |
533 properties_map_[dbus::ObjectPath(kMotorolaKeyboardPath)] = properties; | |
534 device_list_.push_back(dbus::ObjectPath(kMotorolaKeyboardPath)); | |
535 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
536 DeviceAdded(dbus::ObjectPath(kMotorolaKeyboardPath))); | |
537 } | |
538 | |
539 if (std::find(device_list_.begin(), device_list_.end(), | |
540 dbus::ObjectPath(kSonyHeadphonesPath)) == | |
541 device_list_.end()) { | |
542 Properties* properties = new Properties(base::Bind( | |
543 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
544 base::Unretained(this), | |
545 dbus::ObjectPath(kSonyHeadphonesPath))); | |
546 properties->address.ReplaceValue(kSonyHeadphonesAddress); | |
547 properties->bluetooth_class.ReplaceValue(kSonyHeadphonesClass); | |
548 properties->name.ReplaceValue("Fake Sony Headphones"); | |
549 properties->alias.ReplaceValue(kSonyHeadphonesName); | |
550 properties->adapter.ReplaceValue( | |
551 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
552 | |
553 properties_map_[dbus::ObjectPath(kSonyHeadphonesPath)] = properties; | |
554 device_list_.push_back(dbus::ObjectPath(kSonyHeadphonesPath)); | |
555 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
556 DeviceAdded(dbus::ObjectPath(kSonyHeadphonesPath))); | |
557 } | |
558 | |
559 } else if (discovery_simulation_step_ == 10) { | |
560 if (std::find(device_list_.begin(), device_list_.end(), | |
561 dbus::ObjectPath(kPhonePath)) == device_list_.end()) { | |
562 Properties* properties = new Properties(base::Bind( | |
563 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
564 base::Unretained(this), | |
565 dbus::ObjectPath(kPhonePath))); | |
566 properties->address.ReplaceValue(kPhoneAddress); | |
567 properties->bluetooth_class.ReplaceValue(kPhoneClass); | |
568 properties->name.ReplaceValue("Fake Phone"); | |
569 properties->alias.ReplaceValue(kPhoneName); | |
570 properties->adapter.ReplaceValue( | |
571 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
572 | |
573 properties_map_[dbus::ObjectPath(kPhonePath)] = properties; | |
574 device_list_.push_back(dbus::ObjectPath(kPhonePath)); | |
575 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
576 DeviceAdded(dbus::ObjectPath(kPhonePath))); | |
577 } | |
578 | |
579 if (std::find(device_list_.begin(), device_list_.end(), | |
580 dbus::ObjectPath(kWeirdDevicePath)) == device_list_.end()) { | |
581 Properties* properties = new Properties(base::Bind( | |
582 &FakeBluetoothDeviceClient::OnPropertyChanged, | |
583 base::Unretained(this), | |
584 dbus::ObjectPath(kWeirdDevicePath))); | |
585 properties->address.ReplaceValue(kWeirdDeviceAddress); | |
586 properties->bluetooth_class.ReplaceValue(kWeirdDeviceClass); | |
587 properties->name.ReplaceValue("Fake Weird Device"); | |
588 properties->alias.ReplaceValue(kWeirdDeviceName); | |
589 properties->adapter.ReplaceValue( | |
590 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); | |
591 | |
592 properties_map_[dbus::ObjectPath(kWeirdDevicePath)] = properties; | |
593 device_list_.push_back(dbus::ObjectPath(kWeirdDevicePath)); | |
594 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_, | |
595 DeviceAdded(dbus::ObjectPath(kWeirdDevicePath))); | |
596 } | |
597 | |
598 } else if (discovery_simulation_step_ == 13) { | |
599 RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), | |
600 dbus::ObjectPath(kVanishingDevicePath)); | |
601 | |
602 } else if (discovery_simulation_step_ == 14) { | |
603 return; | |
604 | |
605 } | |
606 | |
607 ++discovery_simulation_step_; | |
608 MessageLoop::current()->PostDelayedTask( | |
609 FROM_HERE, | |
610 base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, | |
611 base::Unretained(this)), | |
612 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
613 } | |
614 | |
615 | |
616 void FakeBluetoothDeviceClient::CompleteSimulatedPairing( | |
617 const dbus::ObjectPath& object_path, | |
618 const base::Closure& callback, | |
619 const ErrorCallback& error_callback) { | |
620 VLOG(1) << "CompleteSimulatedPairing: " << object_path.value(); | |
621 if (pairing_cancelled_) { | |
622 pairing_cancelled_ = false; | |
623 | |
624 error_callback.Run(bluetooth_adapter::kErrorAuthenticationCanceled, | |
625 "Cancaled"); | |
626 } else { | |
627 Properties* properties = GetProperties(object_path); | |
628 | |
629 properties->paired.ReplaceValue(true); | |
630 | |
631 callback.Run(); | |
632 properties->NotifyPropertyChanged(properties->paired.name()); | |
633 } | |
634 } | |
635 | |
636 void FakeBluetoothDeviceClient::TimeoutSimulatedPairing( | |
637 const dbus::ObjectPath& object_path, | |
638 const ErrorCallback& error_callback) { | |
639 VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value(); | |
640 | |
641 error_callback.Run(bluetooth_adapter::kErrorAuthenticationTimeout, | |
642 "Timed out"); | |
643 } | |
644 | |
645 void FakeBluetoothDeviceClient::CancelSimulatedPairing( | |
646 const dbus::ObjectPath& object_path, | |
647 const ErrorCallback& error_callback) { | |
648 VLOG(1) << "CancelSimulatedPairing: " << object_path.value(); | |
649 | |
650 error_callback.Run(bluetooth_adapter::kErrorAuthenticationCanceled, | |
651 "Canceled"); | |
652 } | |
653 | |
654 void FakeBluetoothDeviceClient::RejectSimulatedPairing( | |
655 const dbus::ObjectPath& object_path, | |
656 const ErrorCallback& error_callback) { | |
657 VLOG(1) << "RejectSimulatedPairing: " << object_path.value(); | |
658 | |
659 error_callback.Run(bluetooth_adapter::kErrorAuthenticationRejected, | |
660 "Rejected"); | |
661 } | |
662 | |
663 void FakeBluetoothDeviceClient::PinCodeCallback( | |
664 const dbus::ObjectPath& object_path, | |
665 const base::Closure& callback, | |
666 const ErrorCallback& error_callback, | |
667 ExperimentalBluetoothAgentServiceProvider::Delegate::Status status, | |
668 const std::string& pincode) { | |
669 VLOG(1) << "PinCodeCallback: " << object_path.value(); | |
670 | |
671 if (status == ExperimentalBluetoothAgentServiceProvider::Delegate::SUCCESS) { | |
672 MessageLoop::current()->PostDelayedTask( | |
673 FROM_HERE, | |
674 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
675 base::Unretained(this), | |
676 object_path, callback, error_callback), | |
677 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); | |
678 | |
679 } else if (status == | |
680 ExperimentalBluetoothAgentServiceProvider::Delegate::CANCELLED) { | |
681 MessageLoop::current()->PostDelayedTask( | |
682 FROM_HERE, | |
683 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, | |
684 base::Unretained(this), | |
685 object_path, error_callback), | |
686 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
687 | |
688 } else if (status == | |
689 ExperimentalBluetoothAgentServiceProvider::Delegate::REJECTED) { | |
690 MessageLoop::current()->PostDelayedTask( | |
691 FROM_HERE, | |
692 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, | |
693 base::Unretained(this), | |
694 object_path, error_callback), | |
695 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
696 | |
697 } | |
698 } | |
699 | |
700 void FakeBluetoothDeviceClient::PasskeyCallback( | |
701 const dbus::ObjectPath& object_path, | |
702 const base::Closure& callback, | |
703 const ErrorCallback& error_callback, | |
704 ExperimentalBluetoothAgentServiceProvider::Delegate::Status status, | |
705 uint32 passkey) { | |
706 VLOG(1) << "PasskeyCallback: " << object_path.value(); | |
707 | |
708 if (status == ExperimentalBluetoothAgentServiceProvider::Delegate::SUCCESS) { | |
709 MessageLoop::current()->PostDelayedTask( | |
710 FROM_HERE, | |
711 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
712 base::Unretained(this), | |
713 object_path, callback, error_callback), | |
714 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); | |
715 | |
716 } else if (status == | |
717 ExperimentalBluetoothAgentServiceProvider::Delegate::CANCELLED) { | |
718 MessageLoop::current()->PostDelayedTask( | |
719 FROM_HERE, | |
720 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, | |
721 base::Unretained(this), | |
722 object_path, error_callback), | |
723 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
724 | |
725 } else if (status == | |
726 ExperimentalBluetoothAgentServiceProvider::Delegate::REJECTED) { | |
727 MessageLoop::current()->PostDelayedTask( | |
728 FROM_HERE, | |
729 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, | |
730 base::Unretained(this), | |
731 object_path, error_callback), | |
732 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
733 | |
734 } | |
735 } | |
736 | |
737 void FakeBluetoothDeviceClient::ConfirmationCallback( | |
738 const dbus::ObjectPath& object_path, | |
739 const base::Closure& callback, | |
740 const ErrorCallback& error_callback, | |
741 ExperimentalBluetoothAgentServiceProvider::Delegate::Status status) { | |
742 VLOG(1) << "ConfirmationCallback: " << object_path.value(); | |
743 | |
744 if (status == ExperimentalBluetoothAgentServiceProvider::Delegate::SUCCESS) { | |
745 MessageLoop::current()->PostDelayedTask( | |
746 FROM_HERE, | |
747 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
748 base::Unretained(this), | |
749 object_path, callback, error_callback), | |
750 base::TimeDelta::FromMilliseconds(3 * simulation_interval_ms_)); | |
751 | |
752 } else if (status == | |
753 ExperimentalBluetoothAgentServiceProvider::Delegate::CANCELLED) { | |
754 MessageLoop::current()->PostDelayedTask( | |
755 FROM_HERE, | |
756 base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, | |
757 base::Unretained(this), | |
758 object_path, error_callback), | |
759 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
760 | |
761 } else if (status == | |
762 ExperimentalBluetoothAgentServiceProvider::Delegate::REJECTED) { | |
763 MessageLoop::current()->PostDelayedTask( | |
764 FROM_HERE, | |
765 base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, | |
766 base::Unretained(this), | |
767 object_path, error_callback), | |
768 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
769 | |
770 } | |
771 } | |
772 | |
773 void FakeBluetoothDeviceClient::SimulateKeypress( | |
774 int16 entered, | |
775 const dbus::ObjectPath& object_path, | |
776 const base::Closure& callback, | |
777 const ErrorCallback& error_callback) { | |
778 VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value(); | |
779 | |
780 FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = | |
781 static_cast<FakeBluetoothAgentManagerClient*>( | |
782 DBusThreadManager::Get()-> | |
783 GetExperimentalBluetoothAgentManagerClient()); | |
784 FakeBluetoothAgentServiceProvider* agent_service_provider = | |
785 fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); | |
786 agent_service_provider->DisplayPasskey(object_path, 123456, entered); | |
787 | |
788 if (entered < 6) { | |
789 MessageLoop::current()->PostDelayedTask( | |
790 FROM_HERE, | |
791 base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, | |
792 base::Unretained(this), | |
793 entered + 1, object_path, callback, error_callback), | |
794 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
795 | |
796 } else { | |
797 MessageLoop::current()->PostDelayedTask( | |
798 FROM_HERE, | |
799 base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, | |
800 base::Unretained(this), | |
801 object_path, callback, error_callback), | |
802 base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); | |
803 | |
804 } | |
805 } | |
806 | |
807 } // namespace chromeos | |
OLD | NEW |