1 // Copyright 2014 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 "chrome/browser/ui/webui/chromeos/nfc_debug_ui.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/values.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/common/url_constants.h" 12 #include "chrome/grit/generated_resources.h" 13 #include "content/public/browser/web_ui.h" 14 #include "content/public/browser/web_ui_data_source.h" 15 #include "content/public/browser/web_ui_message_handler.h" 16 #include "device/nfc/nfc_adapter.h" 17 #include "device/nfc/nfc_adapter_factory.h" 18 #include "device/nfc/nfc_peer.h" 19 #include "device/nfc/nfc_tag.h" 20 #include "grit/browser_resources.h" 21 22 using device::NfcAdapter; 23 using device::NfcAdapterFactory; 24 using device::NfcNdefMessage; 25 using device::NfcNdefRecord; 26 using device::NfcNdefTagTechnology; 27 using device::NfcPeer; 28 using device::NfcTag; 29 using device::NfcTagTechnology; 30 31 namespace chromeos { 32 33 namespace { 34 35 // Keys for various NFC properties that are used by JS. 36 const char kAdapterPeersProperty[] = "peers"; 37 const char kAdapterPollingProperty[] = "polling"; 38 const char kAdapterPoweredProperty[] = "powered"; 39 const char kAdapterPresentProperty[] = "present"; 40 const char kAdapterTagsProperty[] = "tags"; 41 42 const char kPeerIdentifierProperty[] = "identifier"; 43 const char kPeerRecordsProperty[] = "records"; 44 45 const char kTagIdentifierProperty[] = "identifier"; 46 const char kTagTypeProperty[] = "type"; 47 const char kTagReadOnlyProperty[] = "readOnly"; 48 const char kTagRecordsProperty[] = "records"; 49 const char kTagSupportedProtocolProperty[] = "supportedProtocol"; 50 const char kTagSupportedTechnologiesProperty[] = "supportedTechnologies"; 51 const char kRecordTypeProperty[] = "type"; 52 53 // Tag types. 54 const char kTagType1[] = "TYPE-1"; 55 const char kTagType2[] = "TYPE-2"; 56 const char kTagType3[] = "TYPE-3"; 57 const char kTagType4[] = "TYPE-4"; 58 const char kTagTypeUnknown[] = "UNKNOWN"; 59 60 // NFC transfer protocols. 61 const char kTagProtocolFelica[] = "FELICA"; 62 const char kTagProtocolIsoDep[] = "ISO-DEP"; 63 const char kTagProtocolJewel[] = "JEWEL"; 64 const char kTagProtocolMifare[] = "MIFARE"; 65 const char kTagProtocolNfcDep[] = "NFC-DEP"; 66 const char kTagProtocolUnknown[] = "UNKNOWN"; 67 68 // NFC tag technologies. 69 const char kTagTechnologyNfcA[] = "NFC-A"; 70 const char kTagTechnologyNfcB[] = "NFC-B"; 71 const char kTagTechnologyNfcF[] = "NFC-F"; 72 const char kTagTechnologyNfcV[] = "NFC-V"; 73 const char kTagTechnologyIsoDep[] = "ISO-DEP"; 74 const char kTagTechnologyNdef[] = "NDEF"; 75 76 // NDEF types. 77 const char kTypeHandoverCarrier[] = "HANDOVER_CARRIER"; 78 const char kTypeHandoverRequest[] = "HANDOVER_REQUEST"; 79 const char kTypeHandoverSelect[] = "HANDOVER_SELECT"; 80 const char kTypeSmartPoster[] = "SMART_POSTER"; 81 const char kTypeText[] = "TEXT"; 82 const char kTypeURI[] = "URI"; 83 const char kTypeUnknown[] = "UNKNOWN"; 84 85 // JavaScript callback constants. 86 const char kInitializeCallback[] = "initialize"; 87 const char kSetAdapterPowerCallback[] = "setAdapterPower"; 88 const char kSetAdapterPollingCallback[] = "setAdapterPolling"; 89 const char kSubmitRecordFormCallback[] = "submitRecordForm"; 90 91 // Constants for JavaScript functions that we can call. 92 const char kOnNfcAdapterInfoChangedFunction[] = 93 "nfcDebug.NfcDebugUI.onNfcAdapterInfoChanged"; 94 const char kOnNfcAvailabilityDeterminedFunction[] = 95 "nfcDebug.NfcDebugUI.onNfcAvailabilityDetermined"; 96 const char kOnNfcPeerDeviceInfoChangedFunction[] = 97 "nfcDebug.NfcDebugUI.onNfcPeerDeviceInfoChanged"; 98 const char kOnNfcTagInfoChangedFunction[] = 99 "nfcDebug.NfcDebugUI.onNfcTagInfoChanged"; 100 const char kOnSetAdapterPollingFailedFunction[] = 101 "nfcDebug.NfcDebugUI.onSetAdapterPollingFailed"; 102 const char kOnSetAdapterPowerFailedFunction[] = 103 "nfcDebug.NfcDebugUI.onSetAdapterPowerFailed"; 104 const char kOnSubmitRecordFormFailedFunction[] = 105 "nfcDebug.NfcDebugUI.onSubmitRecordFormFailed"; 106 107 std::string RecordTypeToString(NfcNdefRecord::Type type) { 108 switch (type) { 109 case NfcNdefRecord::kTypeHandoverCarrier: 110 return kTypeHandoverCarrier; 111 case NfcNdefRecord::kTypeHandoverRequest: 112 return kTypeHandoverRequest; 113 case NfcNdefRecord::kTypeHandoverSelect: 114 return kTypeHandoverSelect; 115 case NfcNdefRecord::kTypeSmartPoster: 116 return kTypeSmartPoster; 117 case NfcNdefRecord::kTypeText: 118 return kTypeText; 119 case NfcNdefRecord::kTypeURI: 120 return kTypeURI; 121 case NfcNdefRecord::kTypeUnknown: 122 return kTypeUnknown; 123 } 124 return kTypeUnknown; 125 } 126 127 NfcNdefRecord::Type RecordTypeStringValueToEnum(const std::string& type) { 128 if (type == kTypeHandoverCarrier) 129 return NfcNdefRecord::kTypeHandoverCarrier; 130 if (type == kTypeHandoverRequest) 131 return NfcNdefRecord::kTypeHandoverRequest; 132 if (type == kTypeHandoverSelect) 133 return NfcNdefRecord::kTypeHandoverSelect; 134 if (type == kTypeSmartPoster) 135 return NfcNdefRecord::kTypeSmartPoster; 136 if (type == kTypeText) 137 return NfcNdefRecord::kTypeText; 138 if (type == kTypeURI) 139 return NfcNdefRecord::kTypeURI; 140 return NfcNdefRecord::kTypeUnknown; 141 } 142 143 std::string TagTypeToString(NfcTag::TagType type) { 144 switch (type) { 145 case NfcTag::kTagType1: 146 return kTagType1; 147 case NfcTag::kTagType2: 148 return kTagType2; 149 case NfcTag::kTagType3: 150 return kTagType3; 151 case NfcTag::kTagType4: 152 return kTagType4; 153 case NfcTag::kTagTypeUnknown: 154 return kTagTypeUnknown; 155 } 156 return kTagTypeUnknown; 157 } 158 159 std::string TagProtocolToString(NfcTag::Protocol protocol) { 160 switch (protocol) { 161 case NfcTag::kProtocolFelica: 162 return kTagProtocolFelica; 163 case NfcTag::kProtocolIsoDep: 164 return kTagProtocolIsoDep; 165 case NfcTag::kProtocolJewel: 166 return kTagProtocolJewel; 167 case NfcTag::kProtocolMifare: 168 return kTagProtocolMifare; 169 case NfcTag::kProtocolNfcDep: 170 return kTagProtocolNfcDep; 171 case NfcTag::kProtocolUnknown: 172 return kTagProtocolUnknown; 173 } 174 return kTagProtocolUnknown; 175 } 176 177 // content::WebUIMessageHandler implementation for this page. 178 class NfcDebugMessageHandler : public content::WebUIMessageHandler, 179 public NfcAdapter::Observer, 180 public NfcNdefTagTechnology::Observer, 181 public NfcPeer::Observer, 182 public NfcTag::Observer { 183 public: 184 NfcDebugMessageHandler(); 185 virtual ~NfcDebugMessageHandler(); 186 187 // WebUIMessageHandler implementation. 188 virtual void RegisterMessages() OVERRIDE; 189 190 // NfcAdapter::Observer overrides. 191 virtual void AdapterPresentChanged( 192 NfcAdapter* adapter, 193 bool present) OVERRIDE; 194 virtual void AdapterPoweredChanged( 195 NfcAdapter* adapter, 196 bool powered) OVERRIDE; 197 virtual void AdapterPollingChanged( 198 NfcAdapter* adapter, 199 bool polling) OVERRIDE; 200 virtual void TagFound(NfcAdapter* adapter, NfcTag* tag) OVERRIDE; 201 virtual void TagLost(NfcAdapter*adapter, NfcTag* tag) OVERRIDE; 202 virtual void PeerFound(NfcAdapter* adaper, NfcPeer* peer) OVERRIDE; 203 virtual void PeerLost(NfcAdapter* adapter, NfcPeer* peer) OVERRIDE; 204 205 // NfcNdefTagTechnology::Observer override. 206 virtual void RecordReceived( 207 NfcTag* tag, 208 const NfcNdefRecord* record) OVERRIDE; 209 210 // NfcPeer::Observer override. 211 virtual void RecordReceived( 212 NfcPeer* peer, 213 const NfcNdefRecord* record) OVERRIDE; 214 215 // NfcTag::Observer override. 216 virtual void TagReady(NfcTag* tag) OVERRIDE; 217 218 private: 219 // Called by the UI when the page loads. This method requests information 220 // about NFC availability on the current platform and requests the underlying 221 // Adapter object. The UI is notified once the information is available. 222 void Initialize(const base::ListValue* args); 223 224 // Called by the UI to toggle the adapter power. |args| will contain one 225 // boolean that indicates whether the power should be set to ON or OFF. 226 void SetAdapterPower(const base::ListValue* args); 227 void OnSetAdapterPowerError(); 228 229 // Called by the UI set the adapter's poll status. |args| will contain one 230 // boolean that indicates whether polling should be started or stopped. 231 void SetAdapterPolling(const base::ListValue* args); 232 void OnSetAdapterPollingError(); 233 234 // Called by the UI to push an NDEF record to a remote device or tag. |args| 235 // will contain one dictionary that contains the record data. 236 void SubmitRecordForm(const base::ListValue* args); 237 void OnSubmitRecordFormFailed(const std::string& error_message); 238 239 // Callback passed to NfcAdapterFactory::GetAdapter. 240 void OnGetAdapter(scoped_refptr<NfcAdapter> adapter); 241 242 // Stores the properties of the NFC adapter in |out|, mapping these to keys 243 // that will be read by JS. 244 void GetAdapterProperties(base::DictionaryValue* out); 245 246 // Stores the properties of the NFC peer in |out|, mapping these to keys 247 // that will be read by JS. |out| will not be modified, if no peer is known. 248 void GetPeerProperties(base::DictionaryValue* out); 249 250 // Stores the properties of the NFC tag in |out|, mapping these to keys 251 // that will be read by JS. |out| will not be modified, if no tag is known. 252 void GetTagProperties(base::DictionaryValue* out); 253 254 // Returns the records in |message| by populating |out|, in which 255 // they have been converted to a JS friendly format. 256 void GetRecordList(const NfcNdefMessage& message, base::ListValue* out); 257 258 // Updates the data displayed in the UI for the current adapter. 259 void UpdateAdapterInfo(); 260 261 // Updates the data displayed in the UI for the current peer. 262 void UpdatePeerInfo(); 263 264 // Updates the data displayed in the UI for the current tag. 265 void UpdateTagInfo(); 266 267 // The NfcAdapter object. 268 scoped_refptr<NfcAdapter> nfc_adapter_; 269 270 // The cached identifier of the most recent NFC peer device found. 271 std::string peer_identifier_; 272 273 // The cached identifier of the most recent NFC tag found. 274 std::string tag_identifier_; 275 276 DISALLOW_COPY_AND_ASSIGN(NfcDebugMessageHandler); 277 }; 278 279 NfcDebugMessageHandler::NfcDebugMessageHandler() { 280 } 281 282 NfcDebugMessageHandler::~NfcDebugMessageHandler() { 283 if (!nfc_adapter_.get()) 284 return; 285 nfc_adapter_->RemoveObserver(this); 286 if (!peer_identifier_.empty()) { 287 NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_); 288 if (peer) 289 peer->RemoveObserver(this); 290 } 291 if (!tag_identifier_.empty()) { 292 NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_); 293 if (tag) 294 tag->RemoveObserver(this); 295 } 296 } 297 298 void NfcDebugMessageHandler::AdapterPresentChanged( 299 NfcAdapter* adapter, 300 bool present) { 301 UpdateAdapterInfo(); 302 } 303 304 void NfcDebugMessageHandler::AdapterPoweredChanged( 305 NfcAdapter* adapter, 306 bool powered) { 307 UpdateAdapterInfo(); 308 } 309 310 void NfcDebugMessageHandler::AdapterPollingChanged( 311 NfcAdapter* adapter, 312 bool polling) { 313 UpdateAdapterInfo(); 314 } 315 316 void NfcDebugMessageHandler::TagFound(NfcAdapter* adapter, NfcTag* tag) { 317 VLOG(1) << "Found NFC tag: " << tag->GetIdentifier(); 318 tag->AddObserver(this); 319 tag_identifier_ = tag->GetIdentifier(); 320 tag->GetNdefTagTechnology()->AddObserver(this); 321 UpdateAdapterInfo(); 322 UpdateTagInfo(); 323 } 324 325 void NfcDebugMessageHandler::TagLost(NfcAdapter*adapter, NfcTag* tag) { 326 VLOG(1) << "Lost NFC tag: " << tag->GetIdentifier(); 327 tag->RemoveObserver(this); 328 tag->GetNdefTagTechnology()->RemoveObserver(this); 329 tag_identifier_.clear(); 330 UpdateAdapterInfo(); 331 UpdateTagInfo(); 332 } 333 334 void NfcDebugMessageHandler::PeerFound(NfcAdapter* adaper, NfcPeer* peer) { 335 VLOG(1) << "Found NFC peer device: " << peer->GetIdentifier(); 336 peer->AddObserver(this); 337 peer_identifier_ = peer->GetIdentifier(); 338 UpdateAdapterInfo(); 339 UpdatePeerInfo(); 340 } 341 342 void NfcDebugMessageHandler::PeerLost(NfcAdapter* adapter, NfcPeer* peer) { 343 VLOG(1) << "Lost NFC peer device: " << peer->GetIdentifier(); 344 peer->RemoveObserver(this); 345 peer_identifier_.clear(); 346 UpdateAdapterInfo(); 347 UpdatePeerInfo(); 348 } 349 350 void NfcDebugMessageHandler::RecordReceived( 351 NfcTag* tag, 352 const NfcNdefRecord* record) { 353 if (tag->GetIdentifier() != tag_identifier_) { 354 LOG(WARNING) << "Records received from unknown tag: " 355 << tag->GetIdentifier(); 356 return; 357 } 358 UpdateTagInfo(); 359 } 360 361 void NfcDebugMessageHandler::RecordReceived( 362 NfcPeer* peer, 363 const NfcNdefRecord* record) { 364 if (peer->GetIdentifier() != peer_identifier_) { 365 LOG(WARNING) << "Records received from unknown peer: " 366 << peer->GetIdentifier(); 367 return; 368 } 369 UpdatePeerInfo(); 370 } 371 372 void NfcDebugMessageHandler::TagReady(NfcTag* tag) { 373 if (tag_identifier_ != tag->GetIdentifier()) { 374 LOG(WARNING) << "Unknown tag became ready: " << tag->GetIdentifier(); 375 return; 376 } 377 VLOG(1) << "Tag ready: " << tag->GetIdentifier(); 378 UpdateTagInfo(); 379 } 380 381 void NfcDebugMessageHandler::RegisterMessages() { 382 web_ui()->RegisterMessageCallback( 383 kInitializeCallback, 384 base::Bind(&NfcDebugMessageHandler::Initialize, 385 base::Unretained(this))); 386 web_ui()->RegisterMessageCallback( 387 kSetAdapterPowerCallback, 388 base::Bind(&NfcDebugMessageHandler::SetAdapterPower, 389 base::Unretained(this))); 390 web_ui()->RegisterMessageCallback( 391 kSetAdapterPollingCallback, 392 base::Bind(&NfcDebugMessageHandler::SetAdapterPolling, 393 base::Unretained(this))); 394 web_ui()->RegisterMessageCallback( 395 kSubmitRecordFormCallback, 396 base::Bind(&NfcDebugMessageHandler::SubmitRecordForm, 397 base::Unretained(this))); 398 } 399 400 void NfcDebugMessageHandler::Initialize(const base::ListValue* args) { 401 bool nfc_available = NfcAdapterFactory::IsNfcAvailable(); 402 base::FundamentalValue available(nfc_available); 403 web_ui()->CallJavascriptFunction(kOnNfcAvailabilityDeterminedFunction, 404 available); 405 if (!nfc_available) { 406 LOG(WARNING) << "NFC is not available on current platform."; 407 return; 408 } 409 NfcAdapterFactory::GetAdapter( 410 base::Bind(&NfcDebugMessageHandler::OnGetAdapter, 411 base::Unretained(this))); 412 } 413 414 void NfcDebugMessageHandler::SetAdapterPower(const base::ListValue* args) { 415 DCHECK(1 == args->GetSize()); 416 DCHECK(nfc_adapter_.get()); 417 bool powered; 418 args->GetBoolean(0, &powered); 419 VLOG(1) << "Setting adapter power: " << powered; 420 nfc_adapter_->SetPowered( 421 powered, base::Bind(&base::DoNothing), 422 base::Bind(&NfcDebugMessageHandler::OnSetAdapterPowerError, 423 base::Unretained(this))); 424 } 425 426 void NfcDebugMessageHandler::OnSetAdapterPowerError() { 427 LOG(ERROR) << "Failed to set NFC adapter power."; 428 web_ui()->CallJavascriptFunction(kOnSetAdapterPowerFailedFunction); 429 } 430 431 void NfcDebugMessageHandler::SetAdapterPolling(const base::ListValue* args) { 432 DCHECK(1 == args->GetSize()); 433 DCHECK(nfc_adapter_.get()); 434 bool start = false; 435 bool result = args->GetBoolean(0, &start); 436 DCHECK(result); 437 if (start) { 438 VLOG(1) << "Starting NFC poll loop."; 439 nfc_adapter_->StartPolling( 440 base::Bind(&base::DoNothing), 441 base::Bind(&NfcDebugMessageHandler::OnSetAdapterPollingError, 442 base::Unretained(this))); 443 } else { 444 VLOG(1) << "Stopping NFC poll loop."; 445 nfc_adapter_->StopPolling( 446 base::Bind(&base::DoNothing), 447 base::Bind(&NfcDebugMessageHandler::OnSetAdapterPollingError, 448 base::Unretained(this))); 449 } 450 } 451 452 void NfcDebugMessageHandler::OnSetAdapterPollingError() { 453 LOG(ERROR) << "Failed to start/stop polling."; 454 web_ui()->CallJavascriptFunction(kOnSetAdapterPollingFailedFunction); 455 } 456 457 void NfcDebugMessageHandler::SubmitRecordForm(const base::ListValue* args) { 458 DCHECK(1 == args->GetSize()); 459 DCHECK(nfc_adapter_.get()); 460 const base::DictionaryValue* record_data_const = NULL; 461 if (!args->GetDictionary(0, &record_data_const)) { 462 NOTREACHED(); 463 return; 464 } 465 466 if (peer_identifier_.empty() && tag_identifier_.empty()) { 467 OnSubmitRecordFormFailed("No peer or tag present."); 468 return; 469 } 470 471 std::string type; 472 if (!record_data_const->GetString(kRecordTypeProperty, &type)) { 473 OnSubmitRecordFormFailed("Record type not provided."); 474 return; 475 } 476 477 base::DictionaryValue* record_data = record_data_const->DeepCopy(); 478 record_data->Remove(kRecordTypeProperty, NULL); 479 480 // Convert the "targetSize" field to a double, in case JS stored it as an 481 // integer. 482 int target_size; 483 if (record_data->GetInteger(NfcNdefRecord::kFieldTargetSize, &target_size)) { 484 record_data->SetDouble(NfcNdefRecord::kFieldTargetSize, 485 static_cast<double>(target_size)); 486 } 487 488 NfcNdefRecord record; 489 if (!record.Populate(RecordTypeStringValueToEnum(type), record_data)) { 490 OnSubmitRecordFormFailed("Invalid record data provided. Missing required " 491 "fields?"); 492 return; 493 } 494 495 if (!peer_identifier_.empty()) { 496 NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_); 497 if (!peer) { 498 OnSubmitRecordFormFailed("The current NFC adapter doesn't seem to know " 499 "about peer: " + peer_identifier_); 500 return; 501 } 502 NfcNdefMessage message; 503 message.AddRecord(&record); 504 peer->PushNdef(message, 505 base::Bind(&base::DoNothing), 506 base::Bind(&NfcDebugMessageHandler::OnSubmitRecordFormFailed, 507 base::Unretained(this), 508 "Failed to push NDEF record.")); 509 return; 510 } 511 NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_); 512 if (!tag) { 513 OnSubmitRecordFormFailed("The current NFC tag doesn't seem to known about " 514 "tag: " + tag_identifier_); 515 return; 516 } 517 NfcNdefMessage message; 518 message.AddRecord(&record); 519 tag->GetNdefTagTechnology()->WriteNdef( 520 message, 521 base::Bind(&base::DoNothing), 522 base::Bind(&NfcDebugMessageHandler::OnSubmitRecordFormFailed, 523 base::Unretained(this), 524 "Failed to write NDEF record.")); 525 } 526 527 void NfcDebugMessageHandler::OnSubmitRecordFormFailed( 528 const std::string& error_message) { 529 LOG(ERROR) << "SubmitRecordForm failed: " << error_message; 530 web_ui()->CallJavascriptFunction(kOnSubmitRecordFormFailedFunction, 531 base::StringValue(error_message)); 532 } 533 534 void NfcDebugMessageHandler::OnGetAdapter( 535 scoped_refptr<NfcAdapter> adapter) { 536 if (nfc_adapter_.get()) 537 return; 538 nfc_adapter_ = adapter; 539 nfc_adapter_->AddObserver(this); 540 UpdateAdapterInfo(); 541 542 NfcAdapter::PeerList peers; 543 nfc_adapter_->GetPeers(&peers); 544 for (NfcAdapter::PeerList::const_iterator iter = peers.begin(); 545 iter != peers.end(); ++iter) { 546 PeerFound(nfc_adapter_.get(), *iter); 547 } 548 549 NfcAdapter::TagList tags; 550 nfc_adapter_->GetTags(&tags); 551 for (NfcAdapter::TagList::const_iterator iter = tags.begin(); 552 iter != tags.end(); ++iter) { 553 TagFound(nfc_adapter_.get(), *iter); 554 } 555 } 556 557 void NfcDebugMessageHandler::GetAdapterProperties( 558 base::DictionaryValue* out) { 559 if (!nfc_adapter_.get()) { 560 VLOG(1) << "NFC adapter hasn't been received yet."; 561 return; 562 } 563 out->SetBoolean(kAdapterPresentProperty, nfc_adapter_->IsPresent()); 564 out->SetBoolean(kAdapterPollingProperty, nfc_adapter_->IsPolling()); 565 out->SetBoolean(kAdapterPoweredProperty, nfc_adapter_->IsPowered()); 566 567 NfcAdapter::PeerList peers; 568 nfc_adapter_->GetPeers(&peers); 569 out->SetInteger(kAdapterPeersProperty, static_cast<int>(peers.size())); 570 571 NfcAdapter::TagList tags; 572 nfc_adapter_->GetTags(&tags); 573 out->SetInteger(kAdapterTagsProperty, static_cast<int>(tags.size())); 574 } 575 576 void NfcDebugMessageHandler::GetPeerProperties(base::DictionaryValue* out) { 577 if (peer_identifier_.empty()) { 578 VLOG(1) << "No known peer exists."; 579 return; 580 } 581 if (!nfc_adapter_.get()) { 582 VLOG(1) << "NFC adapter hasn't been received yet."; 583 return; 584 } 585 NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_); 586 if (!peer) { 587 LOG(ERROR) << "The current NFC adapter doesn't seem to know about peer: " 588 << peer_identifier_; 589 return; 590 } 591 out->SetString(kPeerIdentifierProperty, peer_identifier_); 592 593 base::ListValue* records = new base::ListValue(); 594 GetRecordList(peer->GetNdefMessage(), records); 595 out->Set(kPeerRecordsProperty, records); 596 } 597 598 void NfcDebugMessageHandler::GetTagProperties(base::DictionaryValue* out) { 599 if (tag_identifier_.empty()) { 600 VLOG(1) << "No known tag exists."; 601 return; 602 } 603 if (!nfc_adapter_.get()) { 604 VLOG(1) << "NFC adapter hasn't been received yet."; 605 return; 606 } 607 NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_); 608 if (!tag) { 609 LOG(ERROR) << "The current NFC adapter doesn't seem to know about tag: " 610 << tag_identifier_; 611 return; 612 } 613 out->SetString(kTagIdentifierProperty, tag_identifier_); 614 out->SetString(kTagTypeProperty, TagTypeToString(tag->GetType())); 615 out->SetBoolean(kTagReadOnlyProperty, tag->IsReadOnly()); 616 out->SetString(kTagSupportedProtocolProperty, 617 TagProtocolToString(tag->GetSupportedProtocol())); 618 619 base::ListValue* technologies = new base::ListValue(); 620 NfcTagTechnology::TechnologyTypeMask technology_mask = 621 tag->GetSupportedTechnologies(); 622 if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcA) 623 technologies->AppendString(kTagTechnologyNfcA); 624 if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcB) 625 technologies->AppendString(kTagTechnologyNfcB); 626 if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcF) 627 technologies->AppendString(kTagTechnologyNfcF); 628 if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcV) 629 technologies->AppendString(kTagTechnologyNfcV); 630 if (technology_mask & NfcTagTechnology::kTechnologyTypeIsoDep) 631 technologies->AppendString(kTagTechnologyIsoDep); 632 if (technology_mask & NfcTagTechnology::kTechnologyTypeNdef) 633 technologies->AppendString(kTagTechnologyNdef); 634 out->Set(kTagSupportedTechnologiesProperty, technologies); 635 636 base::ListValue* records = new base::ListValue(); 637 GetRecordList(tag->GetNdefTagTechnology()->GetNdefMessage(), records); 638 out->Set(kTagRecordsProperty, records); 639 } 640 641 void NfcDebugMessageHandler::GetRecordList(const NfcNdefMessage& message, 642 base::ListValue* out) { 643 for (NfcNdefMessage::RecordList::const_iterator iter = 644 message.records().begin(); 645 iter != message.records().end(); ++iter) { 646 const NfcNdefRecord* record = (*iter); 647 base::DictionaryValue* record_data = record->data().DeepCopy(); 648 record_data->SetString(kRecordTypeProperty, 649 RecordTypeToString(record->type())); 650 out->Append(record_data); 651 } 652 } 653 654 void NfcDebugMessageHandler::UpdateAdapterInfo() { 655 base::DictionaryValue data; 656 GetAdapterProperties(&data); 657 web_ui()->CallJavascriptFunction(kOnNfcAdapterInfoChangedFunction, data); 658 } 659 660 void NfcDebugMessageHandler::UpdatePeerInfo() { 661 base::DictionaryValue data; 662 GetPeerProperties(&data); 663 web_ui()->CallJavascriptFunction(kOnNfcPeerDeviceInfoChangedFunction, data); 664 } 665 666 void NfcDebugMessageHandler::UpdateTagInfo() { 667 base::DictionaryValue data; 668 GetTagProperties(&data); 669 web_ui()->CallJavascriptFunction(kOnNfcTagInfoChangedFunction, data); 670 } 671 672 } // namespace 673 674 NfcDebugUI::NfcDebugUI(content::WebUI* web_ui) 675 : content::WebUIController(web_ui) { 676 web_ui->AddMessageHandler(new NfcDebugMessageHandler()); 677 678 content::WebUIDataSource* html_source = 679 content::WebUIDataSource::Create(chrome::kChromeUINfcDebugHost); 680 html_source->SetUseJsonJSFormatV2(); 681 682 html_source->AddLocalizedString("titleText", IDS_NFC_DEBUG_TITLE); 683 html_source->AddLocalizedString("notSupportedText", 684 IDS_NFC_DEBUG_NOT_SUPPORTED); 685 html_source->AddLocalizedString("adapterHeaderText", 686 IDS_NFC_DEBUG_ADAPTER_HEADER); 687 html_source->AddLocalizedString("adapterPowerOnText", 688 IDS_NFC_DEBUG_ADAPTER_POWER_ON); 689 html_source->AddLocalizedString("adapterPowerOffText", 690 IDS_NFC_DEBUG_ADAPTER_POWER_OFF); 691 html_source->AddLocalizedString("adapterStartPollText", 692 IDS_NFC_DEBUG_ADAPTER_START_POLL); 693 html_source->AddLocalizedString("adapterStopPollText", 694 IDS_NFC_DEBUG_ADAPTER_STOP_POLL); 695 html_source->AddLocalizedString("ndefFormHeaderText", 696 IDS_NFC_DEBUG_NDEF_FORM_HEADER); 697 html_source->AddLocalizedString("ndefFormTypeTextText", 698 IDS_NFC_DEBUG_NDEF_FORM_TYPE_TEXT); 699 html_source->AddLocalizedString("ndefFormTypeUriText", 700 IDS_NFC_DEBUG_NDEF_FORM_TYPE_URI); 701 html_source->AddLocalizedString("ndefFormTypeSmartPosterText", 702 IDS_NFC_DEBUG_NDEF_FORM_TYPE_SMART_POSTER); 703 html_source->AddLocalizedString("ndefFormWriteButtonText", 704 IDS_NFC_DEBUG_NDEF_FORM_WRITE_BUTTON); 705 html_source->AddLocalizedString("ndefFormFieldTextText", 706 IDS_NFC_DEBUG_NDEF_FORM_FIELD_TEXT); 707 html_source->AddLocalizedString("ndefFormFieldEncodingText", 708 IDS_NFC_DEBUG_NDEF_FORM_FIELD_ENCODING); 709 html_source->AddLocalizedString("ndefFormFieldLanguageCodeText", 710 IDS_NFC_DEBUG_NDEF_FORM_FIELD_LANGUAGE_CODE); 711 html_source->AddLocalizedString("ndefFormFieldUriText", 712 IDS_NFC_DEBUG_NDEF_FORM_FIELD_URI); 713 html_source->AddLocalizedString("ndefFormFieldMimeTypeText", 714 IDS_NFC_DEBUG_NDEF_FORM_FIELD_MIME_TYPE); 715 html_source->AddLocalizedString("ndefFormFieldTargetSizeText", 716 IDS_NFC_DEBUG_NDEF_FORM_FIELD_TARGET_SIZE); 717 html_source->AddLocalizedString("ndefFormFieldTitleTextText", 718 IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_TEXT); 719 html_source->AddLocalizedString("ndefFormFieldTitleEncodingText", 720 IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_ENCODING); 721 html_source->AddLocalizedString( 722 "ndefFormFieldTitleLanguageCodeText", 723 IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_LANGUAGE_CODE); 724 html_source->AddLocalizedString("ndefFormPushButtonText", 725 IDS_NFC_DEBUG_NDEF_FORM_PUSH_BUTTON); 726 html_source->AddLocalizedString("nfcPeerHeaderText", 727 IDS_NFC_DEBUG_NFC_PEER_HEADER); 728 html_source->AddLocalizedString("nfcTagHeaderText", 729 IDS_NFC_DEBUG_NFC_TAG_HEADER); 730 html_source->AddLocalizedString("recordsHeaderText", 731 IDS_NFC_DEBUG_RECORDS_HEADER); 732 html_source->AddLocalizedString("errorFailedToSetPowerText", 733 IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POWER); 734 html_source->AddLocalizedString("errorFailedToSetPollingText", 735 IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POLLING); 736 html_source->AddLocalizedString("errorFailedToSubmitPrefixText", 737 IDS_NFC_DEBUG_ERROR_FAILED_TO_SUBMIT_PREFIX); 738 html_source->SetJsonPath("strings.js"); 739 740 // Add required resources. 741 html_source->AddResourcePath("nfc_debug.css", IDR_NFC_DEBUG_CSS); 742 html_source->AddResourcePath("nfc_debug.js", IDR_NFC_DEBUG_JS); 743 html_source->SetDefaultResource(IDR_NFC_DEBUG_HTML); 744 745 Profile* profile = Profile::FromWebUI(web_ui); 746 content::WebUIDataSource::Add(profile, html_source); 747 } 748 749 NfcDebugUI::~NfcDebugUI() { 750 } 751 752 } // namespace chromeos 753