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_adapter_client.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/time/time.h" 11 #include "chromeos/dbus/dbus_thread_manager.h" 12 #include "chromeos/dbus/fake_bluetooth_device_client.h" 13 #include "dbus/object_path.h" 14 #include "third_party/cros_system_api/dbus/service_constants.h" 15 16 namespace { 17 18 // Amount of time to wait after a command before performing it. 19 const int kCommandEffectsTimeMs = 500; 20 21 } 22 23 namespace chromeos { 24 25 const char FakeBluetoothAdapterClient::kAdapterPath[] = 26 "/fake/hci0"; 27 const char FakeBluetoothAdapterClient::kAdapterName[] = 28 "Fake Adapter"; 29 const char FakeBluetoothAdapterClient::kAdapterAddress[] = 30 "01:1a:2b:1a:2b:03"; 31 32 const char FakeBluetoothAdapterClient::kSecondAdapterPath[] = 33 "/fake/hci1"; 34 const char FakeBluetoothAdapterClient::kSecondAdapterName[] = 35 "Second Fake Adapter"; 36 const char FakeBluetoothAdapterClient::kSecondAdapterAddress[] = 37 "00:de:51:10:01:00"; 38 39 FakeBluetoothAdapterClient::Properties::Properties( 40 const PropertyChangedCallback& callback) 41 : BluetoothAdapterClient::Properties( 42 NULL, 43 bluetooth_adapter::kBluetoothAdapterInterface, 44 callback) { 45 } 46 47 FakeBluetoothAdapterClient::Properties::~Properties() { 48 } 49 50 void FakeBluetoothAdapterClient::Properties::Get( 51 dbus::PropertyBase* property, 52 dbus::PropertySet::GetCallback callback) { 53 VLOG(1) << "Get " << property->name(); 54 callback.Run(false); 55 } 56 57 void FakeBluetoothAdapterClient::Properties::GetAll() { 58 VLOG(1) << "GetAll"; 59 } 60 61 void FakeBluetoothAdapterClient::Properties::Set( 62 dbus::PropertyBase *property, 63 dbus::PropertySet::SetCallback callback) { 64 VLOG(1) << "Set " << property->name(); 65 if (property->name() == powered.name() || property->name() == alias.name()) { 66 callback.Run(true); 67 property->ReplaceValueWithSetValue(); 68 } else { 69 callback.Run(false); 70 } 71 } 72 73 74 FakeBluetoothAdapterClient::FakeBluetoothAdapterClient() 75 : visible_(true), 76 second_visible_(false), 77 discovering_count_(0) { 78 properties_.reset(new Properties(base::Bind( 79 &FakeBluetoothAdapterClient::OnPropertyChanged, 80 base::Unretained(this)))); 81 82 properties_->address.ReplaceValue(kAdapterAddress); 83 properties_->name.ReplaceValue("Fake Adapter (Name)"); 84 properties_->alias.ReplaceValue(kAdapterName); 85 properties_->pairable.ReplaceValue(true); 86 87 second_properties_.reset(new Properties(base::Bind( 88 &FakeBluetoothAdapterClient::OnPropertyChanged, 89 base::Unretained(this)))); 90 91 second_properties_->address.ReplaceValue(kSecondAdapterAddress); 92 second_properties_->name.ReplaceValue("Second Fake Adapter (Name)"); 93 second_properties_->alias.ReplaceValue(kSecondAdapterName); 94 second_properties_->pairable.ReplaceValue(true); 95 } 96 97 FakeBluetoothAdapterClient::~FakeBluetoothAdapterClient() { 98 } 99 100 void FakeBluetoothAdapterClient::AddObserver(Observer* observer) { 101 observers_.AddObserver(observer); 102 } 103 104 void FakeBluetoothAdapterClient::RemoveObserver(Observer* observer) { 105 observers_.RemoveObserver(observer); 106 } 107 108 std::vector<dbus::ObjectPath> FakeBluetoothAdapterClient::GetAdapters() { 109 std::vector<dbus::ObjectPath> object_paths; 110 if (visible_) 111 object_paths.push_back(dbus::ObjectPath(kAdapterPath)); 112 if (second_visible_) 113 object_paths.push_back(dbus::ObjectPath(kSecondAdapterPath)); 114 return object_paths; 115 } 116 117 FakeBluetoothAdapterClient::Properties* 118 FakeBluetoothAdapterClient::GetProperties(const dbus::ObjectPath& object_path) { 119 if (object_path == dbus::ObjectPath(kAdapterPath)) 120 return properties_.get(); 121 else if (object_path == dbus::ObjectPath(kSecondAdapterPath)) 122 return second_properties_.get(); 123 else 124 return NULL; 125 } 126 127 void FakeBluetoothAdapterClient::StartDiscovery( 128 const dbus::ObjectPath& object_path, 129 const base::Closure& callback, 130 const ErrorCallback& error_callback) { 131 if (object_path != dbus::ObjectPath(kAdapterPath)) { 132 error_callback.Run(kNoResponseError, ""); 133 return; 134 } 135 136 ++discovering_count_; 137 VLOG(1) << "StartDiscovery: " << object_path.value() << ", " 138 << "count is now " << discovering_count_; 139 callback.Run(); 140 141 if (discovering_count_ == 1) { 142 properties_->discovering.ReplaceValue(true); 143 144 FakeBluetoothDeviceClient* device_client = 145 static_cast<FakeBluetoothDeviceClient*>( 146 DBusThreadManager::Get()->GetBluetoothDeviceClient()); 147 device_client->BeginDiscoverySimulation(dbus::ObjectPath(kAdapterPath)); 148 } 149 } 150 151 void FakeBluetoothAdapterClient::StopDiscovery( 152 const dbus::ObjectPath& object_path, 153 const base::Closure& callback, 154 const ErrorCallback& error_callback) { 155 if (object_path != dbus::ObjectPath(kAdapterPath)) { 156 error_callback.Run(kNoResponseError, ""); 157 return; 158 } 159 160 if (!discovering_count_) { 161 LOG(WARNING) << "StopDiscovery called when not discovering"; 162 error_callback.Run(kNoResponseError, ""); 163 return; 164 } 165 166 --discovering_count_; 167 VLOG(1) << "StopDiscovery: " << object_path.value() << ", " 168 << "count is now " << discovering_count_; 169 callback.Run(); 170 171 if (discovering_count_ == 0) { 172 FakeBluetoothDeviceClient* device_client = 173 static_cast<FakeBluetoothDeviceClient*>( 174 DBusThreadManager::Get()->GetBluetoothDeviceClient()); 175 device_client->EndDiscoverySimulation(dbus::ObjectPath(kAdapterPath)); 176 177 properties_->discovering.ReplaceValue(false); 178 } 179 } 180 181 void FakeBluetoothAdapterClient::RemoveDevice( 182 const dbus::ObjectPath& object_path, 183 const dbus::ObjectPath& device_path, 184 const base::Closure& callback, 185 const ErrorCallback& error_callback) { 186 if (object_path != dbus::ObjectPath(kAdapterPath)) { 187 error_callback.Run(kNoResponseError, ""); 188 return; 189 } 190 191 VLOG(1) << "RemoveDevice: " << object_path.value() 192 << " " << device_path.value(); 193 callback.Run(); 194 195 FakeBluetoothDeviceClient* device_client = 196 static_cast<FakeBluetoothDeviceClient*>( 197 DBusThreadManager::Get()->GetBluetoothDeviceClient()); 198 device_client->RemoveDevice(dbus::ObjectPath(kAdapterPath), device_path); 199 } 200 201 void FakeBluetoothAdapterClient::SetVisible( 202 bool visible) { 203 if (visible && !visible_) { 204 // Adapter becoming visible 205 visible_ = visible; 206 207 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 208 AdapterAdded(dbus::ObjectPath(kAdapterPath))); 209 210 } else if (visible_ && !visible) { 211 // Adapter becoming invisible 212 visible_ = visible; 213 214 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 215 AdapterRemoved(dbus::ObjectPath(kAdapterPath))); 216 } 217 } 218 219 void FakeBluetoothAdapterClient::SetSecondVisible( 220 bool visible) { 221 if (visible && !second_visible_) { 222 // Second adapter becoming visible 223 second_visible_ = visible; 224 225 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 226 AdapterAdded(dbus::ObjectPath(kSecondAdapterPath))); 227 228 } else if (second_visible_ && !visible) { 229 // Second adapter becoming invisible 230 second_visible_ = visible; 231 232 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 233 AdapterRemoved(dbus::ObjectPath(kSecondAdapterPath))); 234 } 235 } 236 237 void FakeBluetoothAdapterClient::OnPropertyChanged( 238 const std::string& property_name) { 239 if (property_name == properties_->powered.name() && 240 !properties_->powered.value()) { 241 VLOG(1) << "Adapter powered off"; 242 243 if (discovering_count_) { 244 discovering_count_ = 0; 245 properties_->discovering.ReplaceValue(false); 246 } 247 } 248 249 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 250 AdapterPropertyChanged(dbus::ObjectPath(kAdapterPath), 251 property_name)); 252 } 253 254 } // namespace chromeos 255