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_record_client.h" 6 7 #include "base/logging.h" 8 #include "chromeos/dbus/dbus_thread_manager.h" 9 #include "chromeos/dbus/fake_nfc_device_client.h" 10 #include "chromeos/dbus/fake_nfc_tag_client.h" 11 #include "third_party/cros_system_api/dbus/service_constants.h" 12 13 namespace chromeos { 14 15 namespace { 16 17 // Gets and returns the value for |key| in |dictionary| as a string. If |key| is 18 // not found, returns an empty string. 19 std::string GetStringValue(const base::DictionaryValue& dictionary, 20 const std::string& key) { 21 std::string value; 22 bool result = dictionary.GetString(key, &value); 23 24 // Simply return |value|. |value| will remain untouched if 25 // base::DictionaryValue::GetString returns false. 26 DCHECK(result || value.empty()); 27 return value; 28 } 29 30 // Gets and returns the value for |key| in |dictionary| as a double. If |key| is 31 // not found, returns 0. 32 double GetDoubleValue(const base::DictionaryValue& dictionary, 33 const std::string& key) { 34 double value = 0; 35 bool result = dictionary.GetDouble(key, &value); 36 37 // Simply return |value|. |value| will remain untouched if 38 // base::DictionaryValue::GetString returns false. 39 DCHECK(result || !value); 40 return value; 41 } 42 43 } // namespace 44 45 const char FakeNfcRecordClient::kDeviceSmartPosterRecordPath[] = 46 "/fake/device/record0"; 47 const char FakeNfcRecordClient::kDeviceTextRecordPath[] = 48 "/fake/device/record1"; 49 const char FakeNfcRecordClient::kDeviceUriRecordPath[] = "/fake/device/record2"; 50 const char FakeNfcRecordClient::kTagRecordPath[] = "/fake/tag/record0"; 51 52 FakeNfcRecordClient::Properties::Properties( 53 const PropertyChangedCallback& callback) 54 : NfcRecordClient::Properties(NULL, callback) { 55 } 56 57 FakeNfcRecordClient::Properties::~Properties() { 58 } 59 60 void FakeNfcRecordClient::Properties::Get( 61 dbus::PropertyBase* property, 62 dbus::PropertySet::GetCallback callback) { 63 VLOG(1) << "Get " << property->name(); 64 callback.Run(false); 65 } 66 67 void FakeNfcRecordClient::Properties::GetAll() { 68 VLOG(1) << "GetAll"; 69 if (!on_get_all_callback().is_null()) 70 on_get_all_callback().Run(); 71 } 72 73 void FakeNfcRecordClient::Properties::Set( 74 dbus::PropertyBase* property, 75 dbus::PropertySet::SetCallback callback) { 76 VLOG(1) << "Set " << property->name(); 77 callback.Run(false); 78 } 79 80 FakeNfcRecordClient::FakeNfcRecordClient() 81 : device_records_visible_(false), 82 tag_records_visible_(false) { 83 VLOG(1) << "Creating FakeNfcRecordClient"; 84 85 device_smart_poster_record_properties_.reset(new Properties( 86 base::Bind(&FakeNfcRecordClient::OnPropertyChanged, 87 base::Unretained(this), 88 dbus::ObjectPath(kDeviceSmartPosterRecordPath)))); 89 device_smart_poster_record_properties_->SetAllPropertiesReceivedCallback( 90 base::Bind(&FakeNfcRecordClient::OnPropertiesReceived, 91 base::Unretained(this), 92 dbus::ObjectPath(kDeviceSmartPosterRecordPath))); 93 94 device_text_record_properties_.reset(new Properties( 95 base::Bind(&FakeNfcRecordClient::OnPropertyChanged, 96 base::Unretained(this), 97 dbus::ObjectPath(kDeviceTextRecordPath)))); 98 device_text_record_properties_->SetAllPropertiesReceivedCallback( 99 base::Bind(&FakeNfcRecordClient::OnPropertiesReceived, 100 base::Unretained(this), 101 dbus::ObjectPath(kDeviceTextRecordPath))); 102 103 device_uri_record_properties_.reset(new Properties( 104 base::Bind(&FakeNfcRecordClient::OnPropertyChanged, 105 base::Unretained(this), 106 dbus::ObjectPath(kDeviceUriRecordPath)))); 107 device_uri_record_properties_->SetAllPropertiesReceivedCallback( 108 base::Bind(&FakeNfcRecordClient::OnPropertiesReceived, 109 base::Unretained(this), 110 dbus::ObjectPath(kDeviceUriRecordPath))); 111 112 tag_record_properties_.reset(new Properties( 113 base::Bind(&FakeNfcRecordClient::OnPropertyChanged, 114 base::Unretained(this), 115 dbus::ObjectPath(kTagRecordPath)))); 116 } 117 118 FakeNfcRecordClient::~FakeNfcRecordClient() { 119 } 120 121 void FakeNfcRecordClient::Init(dbus::Bus* bus) { 122 } 123 124 void FakeNfcRecordClient::AddObserver(Observer* observer) { 125 observers_.AddObserver(observer); 126 } 127 128 void FakeNfcRecordClient::RemoveObserver(Observer* observer) { 129 observers_.RemoveObserver(observer); 130 } 131 132 std::vector<dbus::ObjectPath> FakeNfcRecordClient::GetRecordsForDevice( 133 const dbus::ObjectPath& device_path) { 134 std::vector<dbus::ObjectPath> record_paths; 135 if (device_records_visible_ && 136 device_path == dbus::ObjectPath(FakeNfcDeviceClient::kDevicePath)) { 137 record_paths.push_back(dbus::ObjectPath(kDeviceSmartPosterRecordPath)); 138 record_paths.push_back(dbus::ObjectPath(kDeviceTextRecordPath)); 139 record_paths.push_back(dbus::ObjectPath(kDeviceUriRecordPath)); 140 } 141 return record_paths; 142 } 143 144 std::vector<dbus::ObjectPath> FakeNfcRecordClient::GetRecordsForTag( 145 const dbus::ObjectPath& tag_path) { 146 std::vector<dbus::ObjectPath> record_paths; 147 if (tag_records_visible_ && tag_path.value() == FakeNfcTagClient::kTagPath) 148 record_paths.push_back(dbus::ObjectPath(kTagRecordPath)); 149 return record_paths; 150 } 151 152 FakeNfcRecordClient::Properties* 153 FakeNfcRecordClient::GetProperties(const dbus::ObjectPath& object_path) { 154 if (device_records_visible_) { 155 if (object_path.value() == kDeviceSmartPosterRecordPath) 156 return device_smart_poster_record_properties_.get(); 157 if (object_path.value() == kDeviceTextRecordPath) 158 return device_text_record_properties_.get(); 159 if (object_path.value() == kDeviceUriRecordPath) 160 return device_uri_record_properties_.get(); 161 return NULL; 162 } 163 if (tag_records_visible_ && object_path.value() == kTagRecordPath) 164 return tag_record_properties_.get(); 165 return NULL; 166 } 167 168 void FakeNfcRecordClient::SetDeviceRecordsVisible(bool visible) { 169 if (device_records_visible_ == visible) { 170 VLOG(1) << "Record visibility is already: " << visible; 171 return; 172 } 173 FakeNfcDeviceClient* device_client = static_cast<FakeNfcDeviceClient*>( 174 DBusThreadManager::Get()->GetNfcDeviceClient()); 175 if (!device_client->device_visible()) { 176 VLOG(1) << "Cannot set records when device is not visible."; 177 return; 178 } 179 if (!visible) { 180 device_client->ClearRecords(); 181 FOR_EACH_OBSERVER( 182 NfcRecordClient::Observer, observers_, 183 RecordRemoved(dbus::ObjectPath(kDeviceSmartPosterRecordPath))); 184 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 185 RecordRemoved(dbus::ObjectPath(kDeviceTextRecordPath))); 186 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 187 RecordRemoved(dbus::ObjectPath(kDeviceUriRecordPath))); 188 device_records_visible_ = visible; 189 return; 190 } 191 device_records_visible_ = visible; 192 std::vector<dbus::ObjectPath> record_paths = 193 GetRecordsForDevice( 194 dbus::ObjectPath(FakeNfcDeviceClient::kDevicePath)); 195 device_client->SetRecords(record_paths); 196 197 // Reassign each property and send signals. 198 FOR_EACH_OBSERVER( 199 NfcRecordClient::Observer, observers_, 200 RecordAdded(dbus::ObjectPath(kDeviceSmartPosterRecordPath))); 201 device_smart_poster_record_properties_->type.ReplaceValue( 202 nfc_record::kTypeSmartPoster); 203 device_smart_poster_record_properties_->uri.ReplaceValue( 204 "http://fake.uri0.fake"); 205 device_smart_poster_record_properties_->mime_type.ReplaceValue("text/fake"); 206 device_smart_poster_record_properties_->size.ReplaceValue(128); 207 device_smart_poster_record_properties_-> 208 representation.ReplaceValue("Fake Title"); 209 device_smart_poster_record_properties_->encoding.ReplaceValue( 210 nfc_record::kEncodingUtf16); 211 device_smart_poster_record_properties_->language.ReplaceValue("en"); 212 OnPropertiesReceived(dbus::ObjectPath(kDeviceSmartPosterRecordPath)); 213 214 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 215 RecordAdded(dbus::ObjectPath(kDeviceTextRecordPath))); 216 device_text_record_properties_->type.ReplaceValue(nfc_record::kTypeText); 217 device_text_record_properties_->representation.ReplaceValue( 218 "Kablosuz \xC4\xb0leti\xC5\x9fim"); 219 device_text_record_properties_->encoding.ReplaceValue( 220 nfc_record::kEncodingUtf8); 221 device_text_record_properties_->language.ReplaceValue("tr"); 222 OnPropertiesReceived(dbus::ObjectPath(kDeviceTextRecordPath)); 223 224 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 225 RecordAdded(dbus::ObjectPath(kDeviceUriRecordPath))); 226 device_uri_record_properties_->type.ReplaceValue(nfc_record::kTypeUri); 227 device_uri_record_properties_->uri.ReplaceValue("file://some/fake/path"); 228 device_uri_record_properties_->mime_type.ReplaceValue("text/fake"); 229 device_uri_record_properties_->size.ReplaceValue(512); 230 OnPropertiesReceived(dbus::ObjectPath(kDeviceUriRecordPath)); 231 } 232 233 void FakeNfcRecordClient::SetTagRecordsVisible(bool visible) { 234 if (tag_records_visible_ == visible) { 235 VLOG(1) << "Record visibility is already: " << visible; 236 return; 237 } 238 FakeNfcTagClient* tag_client = static_cast<FakeNfcTagClient*>( 239 DBusThreadManager::Get()->GetNfcTagClient()); 240 if (!tag_client->tag_visible()) { 241 VLOG(1) << "Cannot set records when tag is not visible."; 242 return; 243 } 244 if (!visible) { 245 tag_client->ClearRecords(); 246 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 247 RecordRemoved(dbus::ObjectPath(kTagRecordPath))); 248 tag_records_visible_ = visible; 249 return; 250 } 251 tag_records_visible_ = visible; 252 std::vector<dbus::ObjectPath> record_paths = 253 GetRecordsForTag(dbus::ObjectPath(FakeNfcTagClient::kTagPath)); 254 tag_client->SetRecords(record_paths); 255 256 // Reassign each property to its current value to trigger a property change 257 // signal. 258 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 259 RecordAdded(dbus::ObjectPath(kTagRecordPath))); 260 tag_record_properties_->type.ReplaceValue( 261 tag_record_properties_->type.value()); 262 tag_record_properties_->representation.ReplaceValue( 263 tag_record_properties_->representation.value()); 264 tag_record_properties_->encoding.ReplaceValue( 265 tag_record_properties_->encoding.value()); 266 tag_record_properties_->language.ReplaceValue( 267 tag_record_properties_->language.value()); 268 tag_record_properties_->uri.ReplaceValue( 269 tag_record_properties_->uri.value()); 270 tag_record_properties_->mime_type.ReplaceValue( 271 tag_record_properties_->mime_type.value()); 272 tag_record_properties_->size.ReplaceValue( 273 tag_record_properties_->size.value()); 274 tag_record_properties_->action.ReplaceValue( 275 tag_record_properties_->action.value()); 276 OnPropertiesReceived(dbus::ObjectPath(kTagRecordPath)); 277 } 278 279 bool FakeNfcRecordClient::WriteTagRecord( 280 const base::DictionaryValue& attributes) { 281 if (attributes.empty()) 282 return false; 283 284 tag_record_properties_->type.ReplaceValue( 285 GetStringValue(attributes, nfc_record::kTypeProperty)); 286 tag_record_properties_->encoding.ReplaceValue( 287 GetStringValue(attributes, nfc_record::kEncodingProperty)); 288 tag_record_properties_->language.ReplaceValue( 289 GetStringValue(attributes, nfc_record::kLanguageProperty)); 290 tag_record_properties_->representation.ReplaceValue( 291 GetStringValue(attributes, nfc_record::kRepresentationProperty)); 292 tag_record_properties_->uri.ReplaceValue( 293 GetStringValue(attributes, nfc_record::kUriProperty)); 294 tag_record_properties_->mime_type.ReplaceValue( 295 GetStringValue(attributes, nfc_record::kMimeTypeProperty)); 296 tag_record_properties_->action.ReplaceValue( 297 GetStringValue(attributes, nfc_record::kActionProperty)); 298 tag_record_properties_->size.ReplaceValue(static_cast<uint32>( 299 GetDoubleValue(attributes, nfc_record::kSizeProperty))); 300 301 SetTagRecordsVisible(false); 302 SetTagRecordsVisible(true); 303 304 return true; 305 } 306 307 void FakeNfcRecordClient::OnPropertyChanged( 308 const dbus::ObjectPath& object_path, 309 const std::string& property_name) { 310 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 311 RecordPropertyChanged(object_path, property_name)); 312 } 313 314 void FakeNfcRecordClient::OnPropertiesReceived( 315 const dbus::ObjectPath& object_path) { 316 FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_, 317 RecordPropertiesReceived(object_path)); 318 } 319 320 } // namespace chromeos 321