// 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_tag_client.h" #include "base/location.h" #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.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 "dbus/object_path.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { using nfc_client_helpers::ObjectPathVector; const char FakeNfcTagClient::kTagPath[] = "/fake/tag0"; const int FakeNfcTagClient::kDefaultSimulationTimeoutMilliseconds = 20000; FakeNfcTagClient::Properties::Properties( const PropertyChangedCallback& callback) : NfcTagClient::Properties(NULL, callback) { } FakeNfcTagClient::Properties::~Properties() { } void FakeNfcTagClient::Properties::Get( dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); callback.Run(false); } void FakeNfcTagClient::Properties::GetAll() { VLOG(1) << "GetAll"; } void FakeNfcTagClient::Properties::Set( dbus::PropertyBase* property, dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); callback.Run(false); } FakeNfcTagClient::FakeNfcTagClient() : pairing_started_(false), tag_visible_(false), simulation_timeout_(kDefaultSimulationTimeoutMilliseconds) { VLOG(1) << "Creating FakeNfcTagClient"; properties_.reset(new Properties( base::Bind(&FakeNfcTagClient::OnPropertyChanged, base::Unretained(this), dbus::ObjectPath(kTagPath)))); } FakeNfcTagClient::~FakeNfcTagClient() { } void FakeNfcTagClient::Init(dbus::Bus* bus) { } void FakeNfcTagClient::AddObserver(Observer* observer) { observers_.AddObserver(observer); } void FakeNfcTagClient::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } std::vector FakeNfcTagClient::GetTagsForAdapter( const dbus::ObjectPath& adapter_path) { std::vector tag_paths; if (tag_visible_ && adapter_path.value() == FakeNfcAdapterClient::kAdapterPath0) tag_paths.push_back(dbus::ObjectPath(kTagPath)); return tag_paths; } FakeNfcTagClient::Properties* FakeNfcTagClient::GetProperties(const dbus::ObjectPath& object_path) { if (!tag_visible_) return NULL; return properties_.get(); } void FakeNfcTagClient::Write( const dbus::ObjectPath& object_path, const base::DictionaryValue& attributes, const base::Closure& callback, const nfc_client_helpers::ErrorCallback& error_callback) { VLOG(1) << "FakeNfcTagClient::Write called. Nothing happened."; if (!tag_visible_ || object_path.value() != kTagPath) { LOG(ERROR) << "No such tag: " << object_path.value(); error_callback.Run(nfc_error::kDoesNotExist, "No such tag."); return; } FakeNfcRecordClient* record_client = static_cast( DBusThreadManager::Get()->GetNfcRecordClient()); if (!record_client->WriteTagRecord(attributes)) { LOG(ERROR) << "Failed to tag: " << object_path.value(); error_callback.Run(nfc_error::kFailed, "Failed."); return; } // Success! callback.Run(); } void FakeNfcTagClient::BeginPairingSimulation(int visibility_delay) { if (pairing_started_) { VLOG(1) << "Simulation already started."; return; } DCHECK(!tag_visible_); DCHECK(visibility_delay >= 0); pairing_started_ = true; base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::Bind(&FakeNfcTagClient::MakeTagVisible, base::Unretained(this)), base::TimeDelta::FromMilliseconds(visibility_delay)); } void FakeNfcTagClient::EndPairingSimulation() { if (!pairing_started_) { VLOG(1) << "No simulation started."; return; } pairing_started_ = false; if (!tag_visible_) return; // Remove records, if they were added. if (!properties_->records.value().empty()) { FakeNfcRecordClient* record_client = static_cast( DBusThreadManager::Get()->GetNfcRecordClient()); record_client->SetTagRecordsVisible(false); } // Remove the tag. FOR_EACH_OBSERVER(Observer, observers_, TagRemoved(dbus::ObjectPath(kTagPath))); FakeNfcAdapterClient* adapter_client = static_cast( DBusThreadManager::Get()->GetNfcAdapterClient()); adapter_client->UnsetTag(dbus::ObjectPath(kTagPath)); tag_visible_ = false; } void FakeNfcTagClient::EnableSimulationTimeout(int simulation_timeout) { DCHECK(simulation_timeout >= 0); simulation_timeout_ = simulation_timeout; } void FakeNfcTagClient::DisableSimulationTimeout() { simulation_timeout_ = -1; } void FakeNfcTagClient::SetRecords( const std::vector& record_paths) { if (!tag_visible_) { VLOG(1) << "Tag not visible."; return; } properties_->records.ReplaceValue(record_paths); } void FakeNfcTagClient::ClearRecords() { ObjectPathVector records; SetRecords(records); } void FakeNfcTagClient::OnPropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) { FOR_EACH_OBSERVER(Observer, observers_, TagPropertyChanged(object_path, property_name)); } void FakeNfcTagClient::MakeTagVisible() { if (!pairing_started_) { VLOG(1) << "Tag pairing was cancelled."; return; } tag_visible_ = true; // Set the tag properties. FakeNfcAdapterClient* adapter_client = static_cast( DBusThreadManager::Get()->GetNfcAdapterClient()); adapter_client->SetTag(dbus::ObjectPath(kTagPath)); FOR_EACH_OBSERVER(Observer, observers_, TagAdded(dbus::ObjectPath(kTagPath))); properties_->type.ReplaceValue(nfc_tag::kTagType2); properties_->protocol.ReplaceValue(nfc_common::kProtocolNfcDep); properties_->read_only.ReplaceValue(false); FOR_EACH_OBSERVER(Observer, observers_, TagPropertiesReceived(dbus::ObjectPath(kTagPath))); if (simulation_timeout_ >= 0) { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::Bind(&FakeNfcTagClient::HandleSimulationTimeout, base::Unretained(this)), base::TimeDelta::FromMilliseconds(simulation_timeout_)); return; } } void FakeNfcTagClient::HandleSimulationTimeout() { if (simulation_timeout_ < 0) { VLOG(1) << "Simulation timeout was cancelled. Nothing to do."; return; } EndPairingSimulation(); } } // namespace chromeos