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