1 // Copyright 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_nfc_device_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_nfc_adapter_client.h" 13 #include "chromeos/dbus/fake_nfc_record_client.h" 14 #include "chromeos/dbus/nfc_client_helpers.h" 15 #include "dbus/object_path.h" 16 #include "third_party/cros_system_api/dbus/service_constants.h" 17 18 namespace chromeos { 19 20 using nfc_client_helpers::ObjectPathVector; 21 22 const char FakeNfcDeviceClient::kDevicePath[] = "/fake/device0"; 23 const int FakeNfcDeviceClient::kDefaultSimulationTimeoutMilliseconds = 10000; 24 25 FakeNfcDeviceClient::Properties::Properties( 26 const PropertyChangedCallback& callback) 27 : NfcDeviceClient::Properties(NULL, callback) { 28 } 29 30 FakeNfcDeviceClient::Properties::~Properties() { 31 } 32 33 void FakeNfcDeviceClient::Properties::Get( 34 dbus::PropertyBase* property, 35 dbus::PropertySet::GetCallback callback) { 36 VLOG(1) << "Get " << property->name(); 37 callback.Run(false); 38 } 39 40 void FakeNfcDeviceClient::Properties::GetAll() { 41 VLOG(1) << "GetAll"; 42 } 43 44 void FakeNfcDeviceClient::Properties::Set( 45 dbus::PropertyBase* property, 46 dbus::PropertySet::SetCallback callback) { 47 VLOG(1) << "Set " << property->name(); 48 callback.Run(false); 49 } 50 51 FakeNfcDeviceClient::FakeNfcDeviceClient() 52 : pairing_started_(false), 53 device_visible_(false), 54 simulation_timeout_(kDefaultSimulationTimeoutMilliseconds) { 55 VLOG(1) << "Creating FakeNfcDeviceClient"; 56 57 properties_.reset(new Properties( 58 base::Bind(&FakeNfcDeviceClient::OnPropertyChanged, 59 base::Unretained(this), 60 dbus::ObjectPath(kDevicePath)))); 61 } 62 63 FakeNfcDeviceClient::~FakeNfcDeviceClient() { 64 } 65 66 void FakeNfcDeviceClient::Init(dbus::Bus* bus) { 67 } 68 69 void FakeNfcDeviceClient::AddObserver(Observer* observer) { 70 observers_.AddObserver(observer); 71 } 72 73 void FakeNfcDeviceClient::RemoveObserver(Observer* observer) { 74 observers_.RemoveObserver(observer); 75 } 76 77 std::vector<dbus::ObjectPath> FakeNfcDeviceClient::GetDevicesForAdapter( 78 const dbus::ObjectPath& adapter_path) { 79 std::vector<dbus::ObjectPath> device_paths; 80 if (device_visible_ && 81 adapter_path.value() == FakeNfcAdapterClient::kAdapterPath0) 82 device_paths.push_back(dbus::ObjectPath(kDevicePath)); 83 return device_paths; 84 } 85 86 FakeNfcDeviceClient::Properties* 87 FakeNfcDeviceClient::GetProperties(const dbus::ObjectPath& object_path) { 88 if (!device_visible_) 89 return NULL; 90 return properties_.get(); 91 } 92 93 void FakeNfcDeviceClient::Push( 94 const dbus::ObjectPath& object_path, 95 const base::DictionaryValue& attributes, 96 const base::Closure& callback, 97 const nfc_client_helpers::ErrorCallback& error_callback) { 98 VLOG(1) << "FakeNfcDeviceClient::Write called."; 99 100 // Success! 101 if (!device_visible_) { 102 LOG(ERROR) << "Device not visible. Cannot push record."; 103 error_callback.Run(nfc_error::kDoesNotExist, "No such device."); 104 return; 105 } 106 callback.Run(); 107 } 108 109 void FakeNfcDeviceClient::BeginPairingSimulation(int visibility_delay, 110 int record_push_delay) { 111 if (pairing_started_) { 112 VLOG(1) << "Simulation already started."; 113 return; 114 } 115 DCHECK(!device_visible_); 116 DCHECK(visibility_delay >= 0); 117 118 pairing_started_ = true; 119 120 base::MessageLoop::current()->PostDelayedTask( 121 FROM_HERE, 122 base::Bind(&FakeNfcDeviceClient::MakeDeviceVisible, 123 base::Unretained(this), 124 record_push_delay), 125 base::TimeDelta::FromMilliseconds(visibility_delay)); 126 } 127 128 void FakeNfcDeviceClient::EndPairingSimulation() { 129 if (!pairing_started_) { 130 VLOG(1) << "No simulation started."; 131 return; 132 } 133 if (device_visible_) { 134 // Remove records, if they were added. 135 if (!properties_->records.value().empty()) { 136 FakeNfcRecordClient* record_client = 137 static_cast<FakeNfcRecordClient*>( 138 DBusThreadManager::Get()->GetNfcRecordClient()); 139 record_client->SetDeviceRecordsVisible(false); 140 } 141 // Remove the device. 142 FOR_EACH_OBSERVER(Observer, observers_, 143 DeviceRemoved(dbus::ObjectPath(kDevicePath))); 144 FakeNfcAdapterClient* adapter_client = 145 static_cast<FakeNfcAdapterClient*>( 146 DBusThreadManager::Get()->GetNfcAdapterClient()); 147 adapter_client->UnsetDevice(dbus::ObjectPath(kDevicePath)); 148 device_visible_ = false; 149 } 150 pairing_started_ = false; 151 } 152 153 void FakeNfcDeviceClient::EnableSimulationTimeout(int simulation_timeout) { 154 simulation_timeout_ = simulation_timeout; 155 } 156 157 void FakeNfcDeviceClient::DisableSimulationTimeout() { 158 simulation_timeout_ = -1; 159 } 160 161 void FakeNfcDeviceClient::SetRecords( 162 const std::vector<dbus::ObjectPath>& record_paths) { 163 if (!device_visible_) { 164 VLOG(1) << "Device not visible."; 165 return; 166 } 167 properties_->records.ReplaceValue(record_paths); 168 } 169 170 void FakeNfcDeviceClient::ClearRecords() { 171 ObjectPathVector records; 172 SetRecords(records); 173 } 174 175 void FakeNfcDeviceClient::OnPropertyChanged( 176 const dbus::ObjectPath& object_path, 177 const std::string& property_name) { 178 FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_, 179 DevicePropertyChanged(object_path, property_name)); 180 } 181 182 void FakeNfcDeviceClient::MakeDeviceVisible(int record_push_delay) { 183 if (!pairing_started_) { 184 VLOG(1) << "Device pairing was cancelled."; 185 return; 186 } 187 device_visible_ = true; 188 189 FakeNfcAdapterClient* adapter_client = 190 static_cast<FakeNfcAdapterClient*>( 191 DBusThreadManager::Get()->GetNfcAdapterClient()); 192 adapter_client->SetDevice(dbus::ObjectPath(kDevicePath)); 193 FOR_EACH_OBSERVER(Observer, observers_, 194 DeviceAdded(dbus::ObjectPath(kDevicePath))); 195 196 if (record_push_delay < 0) { 197 // Don't simulate record push. Instead, skip directly to the timeout step. 198 if (simulation_timeout_ >= 0) { 199 base::MessageLoop::current()->PostDelayedTask( 200 FROM_HERE, 201 base::Bind(&FakeNfcDeviceClient::HandleSimulationTimeout, 202 base::Unretained(this)), 203 base::TimeDelta::FromMilliseconds(simulation_timeout_)); 204 } 205 return; 206 } 207 208 base::MessageLoop::current()->PostDelayedTask( 209 FROM_HERE, 210 base::Bind(&FakeNfcDeviceClient::MakeRecordsVisible, 211 base::Unretained(this)), 212 base::TimeDelta::FromMilliseconds(record_push_delay)); 213 } 214 215 void FakeNfcDeviceClient::MakeRecordsVisible() { 216 if (!pairing_started_) { 217 VLOG(1) << "Pairing was cancelled"; 218 return; 219 } 220 DCHECK(device_visible_); 221 FakeNfcRecordClient* record_client = 222 static_cast<FakeNfcRecordClient*>( 223 DBusThreadManager::Get()->GetNfcRecordClient()); 224 record_client->SetDeviceRecordsVisible(true); 225 226 if (simulation_timeout_ < 0) 227 return; 228 229 base::MessageLoop::current()->PostDelayedTask( 230 FROM_HERE, 231 base::Bind(&FakeNfcDeviceClient::HandleSimulationTimeout, 232 base::Unretained(this)), 233 base::TimeDelta::FromMilliseconds(simulation_timeout_)); 234 } 235 236 void FakeNfcDeviceClient::HandleSimulationTimeout() { 237 if (simulation_timeout_ < 0) { 238 VLOG(1) << "Simulation timeout was cancelled. Nothing to do."; 239 return; 240 } 241 EndPairingSimulation(); 242 } 243 244 } // namespace chromeos 245