| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromeos/dbus/fake_nfc_device_client.h" |
| |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/time/time.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/fake_nfc_adapter_client.h" |
| #include "chromeos/dbus/fake_nfc_record_client.h" |
| #include "chromeos/dbus/nfc_client_helpers.h" |
| #include "dbus/object_path.h" |
| #include "third_party/cros_system_api/dbus/service_constants.h" |
| |
| namespace chromeos { |
| |
| using nfc_client_helpers::ObjectPathVector; |
| |
| const char FakeNfcDeviceClient::kDevicePath[] = "/fake/device0"; |
| const int FakeNfcDeviceClient::kDefaultSimulationTimeoutMilliseconds = 10000; |
| |
| FakeNfcDeviceClient::Properties::Properties( |
| const PropertyChangedCallback& callback) |
| : NfcDeviceClient::Properties(NULL, callback) { |
| } |
| |
| FakeNfcDeviceClient::Properties::~Properties() { |
| } |
| |
| void FakeNfcDeviceClient::Properties::Get( |
| dbus::PropertyBase* property, |
| dbus::PropertySet::GetCallback callback) { |
| VLOG(1) << "Get " << property->name(); |
| callback.Run(false); |
| } |
| |
| void FakeNfcDeviceClient::Properties::GetAll() { |
| VLOG(1) << "GetAll"; |
| } |
| |
| void FakeNfcDeviceClient::Properties::Set( |
| dbus::PropertyBase* property, |
| dbus::PropertySet::SetCallback callback) { |
| VLOG(1) << "Set " << property->name(); |
| callback.Run(false); |
| } |
| |
| FakeNfcDeviceClient::FakeNfcDeviceClient() |
| : pairing_started_(false), |
| device_visible_(false), |
| simulation_timeout_(kDefaultSimulationTimeoutMilliseconds) { |
| VLOG(1) << "Creating FakeNfcDeviceClient"; |
| |
| properties_.reset(new Properties( |
| base::Bind(&FakeNfcDeviceClient::OnPropertyChanged, |
| base::Unretained(this), |
| dbus::ObjectPath(kDevicePath)))); |
| } |
| |
| FakeNfcDeviceClient::~FakeNfcDeviceClient() { |
| } |
| |
| void FakeNfcDeviceClient::Init(dbus::Bus* bus) { |
| } |
| |
| void FakeNfcDeviceClient::AddObserver(Observer* observer) { |
| observers_.AddObserver(observer); |
| } |
| |
| void FakeNfcDeviceClient::RemoveObserver(Observer* observer) { |
| observers_.RemoveObserver(observer); |
| } |
| |
| std::vector<dbus::ObjectPath> FakeNfcDeviceClient::GetDevicesForAdapter( |
| const dbus::ObjectPath& adapter_path) { |
| std::vector<dbus::ObjectPath> device_paths; |
| if (device_visible_ && |
| adapter_path.value() == FakeNfcAdapterClient::kAdapterPath0) |
| device_paths.push_back(dbus::ObjectPath(kDevicePath)); |
| return device_paths; |
| } |
| |
| FakeNfcDeviceClient::Properties* |
| FakeNfcDeviceClient::GetProperties(const dbus::ObjectPath& object_path) { |
| if (!device_visible_) |
| return NULL; |
| return properties_.get(); |
| } |
| |
| void FakeNfcDeviceClient::Push( |
| const dbus::ObjectPath& object_path, |
| const base::DictionaryValue& attributes, |
| const base::Closure& callback, |
| const nfc_client_helpers::ErrorCallback& error_callback) { |
| VLOG(1) << "FakeNfcDeviceClient::Write called."; |
| |
| // Success! |
| if (!device_visible_) { |
| LOG(ERROR) << "Device not visible. Cannot push record."; |
| error_callback.Run(nfc_error::kDoesNotExist, "No such device."); |
| return; |
| } |
| callback.Run(); |
| } |
| |
| void FakeNfcDeviceClient::BeginPairingSimulation(int visibility_delay, |
| int record_push_delay) { |
| if (pairing_started_) { |
| VLOG(1) << "Simulation already started."; |
| return; |
| } |
| DCHECK(!device_visible_); |
| DCHECK(visibility_delay >= 0); |
| |
| pairing_started_ = true; |
| |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&FakeNfcDeviceClient::MakeDeviceVisible, |
| base::Unretained(this), |
| record_push_delay), |
| base::TimeDelta::FromMilliseconds(visibility_delay)); |
| } |
| |
| void FakeNfcDeviceClient::EndPairingSimulation() { |
| if (!pairing_started_) { |
| VLOG(1) << "No simulation started."; |
| return; |
| } |
| if (device_visible_) { |
| // Remove records, if they were added. |
| if (!properties_->records.value().empty()) { |
| FakeNfcRecordClient* record_client = |
| static_cast<FakeNfcRecordClient*>( |
| DBusThreadManager::Get()->GetNfcRecordClient()); |
| record_client->SetDeviceRecordsVisible(false); |
| } |
| // Remove the device. |
| FOR_EACH_OBSERVER(Observer, observers_, |
| DeviceRemoved(dbus::ObjectPath(kDevicePath))); |
| FakeNfcAdapterClient* adapter_client = |
| static_cast<FakeNfcAdapterClient*>( |
| DBusThreadManager::Get()->GetNfcAdapterClient()); |
| adapter_client->UnsetDevice(dbus::ObjectPath(kDevicePath)); |
| device_visible_ = false; |
| } |
| pairing_started_ = false; |
| } |
| |
| void FakeNfcDeviceClient::EnableSimulationTimeout(int simulation_timeout) { |
| simulation_timeout_ = simulation_timeout; |
| } |
| |
| void FakeNfcDeviceClient::DisableSimulationTimeout() { |
| simulation_timeout_ = -1; |
| } |
| |
| void FakeNfcDeviceClient::SetRecords( |
| const std::vector<dbus::ObjectPath>& record_paths) { |
| if (!device_visible_) { |
| VLOG(1) << "Device not visible."; |
| return; |
| } |
| properties_->records.ReplaceValue(record_paths); |
| } |
| |
| void FakeNfcDeviceClient::ClearRecords() { |
| ObjectPathVector records; |
| SetRecords(records); |
| } |
| |
| void FakeNfcDeviceClient::OnPropertyChanged( |
| const dbus::ObjectPath& object_path, |
| const std::string& property_name) { |
| FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_, |
| DevicePropertyChanged(object_path, property_name)); |
| } |
| |
| void FakeNfcDeviceClient::MakeDeviceVisible(int record_push_delay) { |
| if (!pairing_started_) { |
| VLOG(1) << "Device pairing was cancelled."; |
| return; |
| } |
| device_visible_ = true; |
| |
| FakeNfcAdapterClient* adapter_client = |
| static_cast<FakeNfcAdapterClient*>( |
| DBusThreadManager::Get()->GetNfcAdapterClient()); |
| adapter_client->SetDevice(dbus::ObjectPath(kDevicePath)); |
| FOR_EACH_OBSERVER(Observer, observers_, |
| DeviceAdded(dbus::ObjectPath(kDevicePath))); |
| |
| if (record_push_delay < 0) { |
| // Don't simulate record push. Instead, skip directly to the timeout step. |
| if (simulation_timeout_ >= 0) { |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&FakeNfcDeviceClient::HandleSimulationTimeout, |
| base::Unretained(this)), |
| base::TimeDelta::FromMilliseconds(simulation_timeout_)); |
| } |
| return; |
| } |
| |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&FakeNfcDeviceClient::MakeRecordsVisible, |
| base::Unretained(this)), |
| base::TimeDelta::FromMilliseconds(record_push_delay)); |
| } |
| |
| void FakeNfcDeviceClient::MakeRecordsVisible() { |
| if (!pairing_started_) { |
| VLOG(1) << "Pairing was cancelled"; |
| return; |
| } |
| DCHECK(device_visible_); |
| FakeNfcRecordClient* record_client = |
| static_cast<FakeNfcRecordClient*>( |
| DBusThreadManager::Get()->GetNfcRecordClient()); |
| record_client->SetDeviceRecordsVisible(true); |
| |
| if (simulation_timeout_ < 0) |
| return; |
| |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&FakeNfcDeviceClient::HandleSimulationTimeout, |
| base::Unretained(this)), |
| base::TimeDelta::FromMilliseconds(simulation_timeout_)); |
| } |
| |
| void FakeNfcDeviceClient::HandleSimulationTimeout() { |
| if (simulation_timeout_ < 0) { |
| VLOG(1) << "Simulation timeout was cancelled. Nothing to do."; |
| return; |
| } |
| EndPairingSimulation(); |
| } |
| |
| } // namespace chromeos |