0

chromeos: Remove unused NFC D-Bus client library

Remove the chrome D-Bus bindings code and web UI test code. We can revive
them from git history if we need them again.

BUG=641996
TEST=compiles
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation
TBR=dpranke@chromium.org

Review-Url: https://codereview.chromium.org/2292703002
Cr-Commit-Position: refs/heads/master@{#415321}
This commit is contained in:
jamescook
2016-08-30 09:50:46 -07:00
committed by Commit bot
parent 82c4e80517
commit 64996a9695
73 changed files with 8 additions and 10677 deletions

@ -453,7 +453,6 @@
#"//content/test:test_support",
#"//device/battery",
#"//device/bluetooth",
#"//device/nfc",
#"//device/usb",
#"//device/vibration",
#"//media/blink",

@ -6074,92 +6074,6 @@ All users must sign out to continue.
For network logs, see: <ph name="DEVICE_LOG_LINK">&lt;a href="chrome://device-log"&gt;chrome://device-log&lt;/a&gt;</ph>
</message>
<!-- About NFC Debug UI display strings. They aren't being internationalized bacause this page is meant for debugging only. -->
<message name="IDS_NFC_DEBUG_TITLE" desc="Title of the debug page meant for developers to test NFC functionality" translateable="false">
NFC API Test Page
</message>
<message name="IDS_NFC_DEBUG_NOT_SUPPORTED" desc="Message shown if the NFC API is not supported on platform" translateable="false">
NFC is not supported on the current platform.
</message>
<message name="IDS_NFC_DEBUG_ADAPTER_HEADER" desc="Header of the 'NFC Adapter' box, that shows the state of the NFC adapter" translateable="false">
NFC Adapter
</message>
<message name="IDS_NFC_DEBUG_ADAPTER_POWER_ON" desc="Adapter power button text to turn the adapter on" translateable="false">
Power ON
</message>
<message name="IDS_NFC_DEBUG_ADAPTER_POWER_OFF" desc="Adapter power button text to turn the adapter off" translateable="false">
Power OFF
</message>
<message name="IDS_NFC_DEBUG_ADAPTER_START_POLL" desc="Adapter poll button text to start polling" translateable="false">
Start Poll
</message>
<message name="IDS_NFC_DEBUG_ADAPTER_STOP_POLL" desc="Adapter poll button text to stop polling" translateable="false">
Stop Poll
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_HEADER" desc="Header of the 'NFC NDEF message form' box used send a message to tag/peer" translateable="false">
Push/Write NDEF Message
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_TYPE_TEXT" desc="NDEF message form dropdown menu item for message type 'Text'" translateable="false">
Text
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_TYPE_URI" desc="NDEF message form dropdown menu item for message type 'URI'" translateable="false">
URI
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_TYPE_SMART_POSTER" desc="NDEF message form dropdown menu text for message type 'SmartPoster'" translateable="false">
SmartPoster
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_TEXT" desc="Label for required input field 'Text'" translateable="false">
Text (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_ENCODING" desc="Label for required input field 'Encoding'" translateable="false">
Encoding (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_LANGUAGE_CODE" desc="Label for required input field 'Language Code'" translateable="false">
Language Code (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_URI" desc="Label for required input field 'URI'" translateable="false">
URI (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_MIME_TYPE" desc="Label for input field 'MIME Type'" translateable="false">
MIME Type:
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_TARGET_SIZE" desc="Label for input field 'Target Size'" translateable="false">
Target Size:
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_TEXT" desc="Label for required input field 'Title Text'" translateable="false">
Title Text (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_ENCODING" desc="Label for required input field 'Title Encoding'" translateable="false">
Title Encoding (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_LANGUAGE_CODE" desc="Label for required input field 'Title Language Code'" translateable="false">
Title Language Code (required):
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_WRITE_BUTTON" desc="NDEF message form button text for writing message to an NFC tag" translateable="false">
Write to Tag
</message>
<message name="IDS_NFC_DEBUG_NDEF_FORM_PUSH_BUTTON" desc="NDEF message form button text for pushing a message to an NFC peer device" translateable="false">
Push to Peer
</message>
<message name="IDS_NFC_DEBUG_NFC_PEER_HEADER" desc="Header of the 'NFC Peer' box" translateable="false">
NDEF Peer
</message>
<message name="IDS_NFC_DEBUG_NFC_TAG_HEADER" desc="Header of the 'NFC Tag' box" translateable="false">
NDEF Tag
</message>
<message name="IDS_NFC_DEBUG_RECORDS_HEADER" desc="Header of the 'Records' section in the tag and peer boxes" translateable="false">
Records
</message>
<message name="IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POWER" desc="Error message shown when adapter power could not be set." translateable="false">
Failed to set adapter power.
</message>
<message name="IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POLLING" desc="Error message shown when polling state could not be set." translateable="false">
Failed to start/stop polling.
</message>
<message name="IDS_NFC_DEBUG_ERROR_FAILED_TO_SUBMIT_PREFIX" desc="Error message shown when an NDEF form could not be submitted." translateable="false">
Failed to submit NDEF:
</message>
<!-- Set time/date UI display strings -->
<message name="IDS_SET_TIME_TITLE" desc="Title of the set time/date UI.">
Check your system time

@ -420,9 +420,6 @@
<include name="IDR_MOBILE_MANIFEST" file="resources\chromeos\mobile_app\manifest.json" type="BINDATA" />
<include name="IDR_MOBILE_SETUP_PAGE_HTML" file="resources\chromeos\mobile_setup.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_MOBILE_SETUP_PORTAL_PAGE_HTML" file="resources\chromeos\mobile_setup_portal.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_NFC_DEBUG_HTML" file="resources\chromeos\nfc_debug.html" type="BINDATA" />
<include name="IDR_NFC_DEBUG_CSS" file="resources\chromeos\nfc_debug.css" type="BINDATA" />
<include name="IDR_NFC_DEBUG_JS" file="resources\chromeos\nfc_debug.js" type="BINDATA" />
<include name="IDR_ECHO_MANIFEST" file="resources\chromeos\echo\manifest.json" type="BINDATA" />
<include name="IDR_MERGE_SESSION_LOAD_HTML" file="resources\chromeos\merge_session_load.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_OS_CREDITS_HTML" file="resources\chromeos\about_os_credits.html" flattenhtml="true" type="BINDATA" />

@ -1,83 +0,0 @@
/* Copyright 2014 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. */
body {
margin: 0
}
p {
white-space: pre-wrap;
}
label {
display: block;
}
h1 {
margin: 1%;
}
div.entity-div {
box-shadow: 0 0 20px 2px #aaa;
display: inline-block;
margin: 10px 5px;
overflow: hidden;
padding: 10px;
vertical-align: top;
}
#nfc-adapter-info {
width: 165px;
}
#ndef-record-form {
width: 300px;
}
#nfc-tag-info,
#nfc-peer-info {
width: 270px;
word-wrap: break-word;
}
#ndef-record-form input {
width: 99%;
}
.parameters-table td {
padding: 0 10px 10px 0;
}
.transition-in {
-webkit-transition: opacity 250ms ease-in-out;
opacity: 1;
transition: opacity 250ms ease-in-out;
}
.transition-out {
-webkit-transition: opacity 250ms ease-in-out;
opacity: 0.25;
transition: opacity 250ms ease-in-out;
}
hr {
background: #888;
border: 0;
border-bottom: 1px dashed #ccc;
}
div.record-key-value-div {
margin-bottom: 10px;
}
span.record-key-span,
div.record-key-div {
font-style: italic;
font-weight: bold;
margin-right: 10px;
}
.record-value-div > * {
margin: 10px;
}

@ -1,131 +0,0 @@
<!doctype html>
<html i18n-values="dir:textdirection;lang:language">
<head>
<meta charset="utf-8">
<title i18n-content="titleText"></title>
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<link rel="stylesheet" type="text/css" href="nfc_debug.css">
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="strings.js"></script>
<script src="nfc_debug.js"></script>
</head>
<body>
<h1 i18n-content="titleText"></h1>
<p id="nfc-not-supported" i18n-content="notSupportedText"></p>
<div id="wrapper">
<div id="nfc-adapter-info" class="entity-div">
<h3 i18n-content="adapterHeaderText"></h3>
<div id="adapter-parameters"></div>
<div id="adapter-toggles">
<button id="power-toggle"></button>
<button id="poll-toggle"></button>
</div>
</div>
<div id="ndef-record-form" class="entity-div">
<h3 i18n-content="ndefFormHeaderText"></h3>
<select id="record-type-menu">
<option i18n-content="ndefFormTypeTextText" value="text"></option>
<option i18n-content="ndefFormTypeUriText" value="uri"></option>
<option i18n-content="ndefFormTypeSmartPosterText" value="smart-poster">
</option>
</select>
<div id="text-form" class="record-form">
<div>
<label for="text-form-text" class="required"
i18n-content="ndefFormFieldTextText">
</label>
<input type="text" id="text-form-text">
</div>
<div>
<label for="text-form-encoding" class="required"
i18n-content="ndefFormFieldEncodingText">
</label>
<input type="text" id="text-form-encoding">
</div>
<div>
<label for="text-form-language-code" class="required"
i18n-content="ndefFormFieldLanguageCodeText">
</label>
<input type="text" id="text-form-language-code">
</div>
</div>
<div id="uri-form" class="record-form">
<div>
<label for="uri-form-uri" class="required"
i18n-content="ndefFormFieldUriText"></label>
<input type="text" id="uri-form-uri">
</div>
<div>
<label for="uri-form-mime-type"
i18n-content="ndefFormFieldMimeTypeText"></label>
<input type="text" id="uri-form-mime-type">
</div>
<div>
<label for="uri-form-target-size"
i18n-content="ndefFormFieldTargetSizeText"></label>
<input type="text" id="uri-form-target-size">
</div>
</div>
<div id="smart-poster-form" class="record-form">
<div>
<label for="smart-poster-form-uri"
i18n-content="ndefFormFieldUriText"></label>
<input type="text" id="smart-poster-form-uri">
</div>
<div>
<label for="smart-poster-form-mime-type"
i18n-content="ndefFormFieldMimeTypeText"></label>
<input type="text" id="smart-poster-form-mime-type">
</div>
<div>
<label for="smart-poster-form-target-size"
i18n-content="ndefFormFieldTargetSizeText"></label>
<input type="text" id="smart-poster-form-target-size">
</div>
<div>
<label for="smart-poster-form-title-text"
i18n-content="ndefFormFieldTitleTextText">
</label>
<input type="text" id="smart-poster-form-title-text">
</div>
<div>
<label for="smart-poster-form-title-encoding"
i18n-content="ndefFormFieldTitleEncodingText">
</label>
<input type="text" id="smart-poster-form-title-encoding">
</div>
<div>
<label for="smart-poster-form-title-language-code"
i18n-content="ndefFormFieldTitleLanguageCodeText">
</label>
<input type="text" id="smart-poster-form-title-language-code">
</div>
</div>
<button id="record-form-submit-button"></button>
</div>
<div id="nfc-peer-info" class="entity-div">
<h3 i18n-content="nfcPeerHeaderText"></h3>
<div id="peer-parameters"></div>
<div id="peer-records-entry" class="records-entry">
<h3 i18n-content="recordsHeaderText"></h3>
<hr/>
<div id="peer-records-container"></div>
<hr/>
</div>
</div>
<div id="nfc-tag-info" class="entity-div">
<h3 i18n-content="nfcTagHeaderText"></h3>
<div id="tag-parameters"></div>
<div id="tag-records-entry" class="records-entry">
<h3 i18n-content="recordsHeaderText"></h3>
<hr/>
<div id="tag-records-container"></div>
<hr/>
</div>
</div>
</div>
<script src="chrome://resources/js/i18n_template.js"></script>
</body>
</html>

@ -1,375 +0,0 @@
// Copyright 2014 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.
cr.define('nfcDebug', function() {
'use strict';
function NfcDebugUI() {
this.adapterData_ = {};
this.peerData_ = {};
this.tagData_ = {};
}
NfcDebugUI.prototype = {
setAdapterData: function(data) {
this.adapterData_ = data;
},
setPeerData: function(data) {
this.peerData_ = data;
},
setTagData: function(data) {
this.tagData_ = data;
},
/**
* Powers the NFC adapter ON or OFF.
*/
toggleAdapterPower: function() {
chrome.send('setAdapterPower', [!this.adapterData_.powered]);
},
/**
* Tells the NFC adapter to start or stop polling.
*/
toggleAdapterPolling: function() {
chrome.send('setAdapterPolling', [!this.adapterData_.polling]);
},
/**
* Notifies the UI that the user made an NDEF type selection and the
* appropriate form should be displayed.
*/
recordTypeChanged: function() {
this.updateRecordFormContents();
},
/**
* Creates a table element and populates it for each record contained
* in the given list of records and adds them as a child of the given
* DOMElement. This method will replace the contents of the given element
* with the tables.
*
* @param {DOMElement} div The container that the records should be rendered
* to.
* @param {Array} records List of NDEF record data.
*/
renderRecords: function(div, records) {
div.textContent = '';
if (records.length == 0) {
return;
}
var self = this;
records.forEach(function(record) {
var recordDiv = document.createElement('div');
recordDiv.setAttribute('class', 'record-div');
for (var key in record) {
if (!record.hasOwnProperty(key))
continue;
var rowDiv = document.createElement('div');
rowDiv.setAttribute('class', 'record-key-value-div');
var keyElement, valueElement;
if (key == 'titles') {
keyElement = document.createElement('div');
keyElement.setAttribute('class', 'record-key-div');
keyElement.appendChild(document.createTextNode(key));
valueElement = document.createElement('div');
valueElement.setAttribute('class', 'record-value-div');
self.renderRecords(valueElement, record[key]);
} else {
keyElement = document.createElement('span');
keyElement.setAttribute('class', 'record-key-span');
keyElement.appendChild(document.createTextNode(key));
valueElement = document.createElement('span');
valueElement.setAttribute('class', 'record-value-span');
valueElement.appendChild(document.createTextNode(record[key]));
}
rowDiv.appendChild(keyElement);
rowDiv.appendChild(valueElement);
recordDiv.appendChild(rowDiv);
}
div.appendChild(recordDiv);
if (records[records.length - 1] !== record)
div.appendChild(document.createElement('hr'));
});
},
/**
* Updates which record type form is displayed based on the currently
* selected type.
*/
updateRecordFormContents: function() {
var recordTypeMenu = $('record-type-menu');
var selectedType =
recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
this.updateRecordFormContentsFromType(selectedType);
},
/**
* Updates which record type form is displayed based on the passed in
* type string.
*
* @param {string} type The record type.
*/
updateRecordFormContentsFromType: function(type) {
$('text-form').hidden = (type != 'text');
$('uri-form').hidden = (type != 'uri');
$('smart-poster-form').hidden = (type != 'smart-poster');
},
/**
* Tries to push or write the record to the remote tag or device based on
* the contents of the record form fields.
*/
submitRecordForm: function() {
var recordTypeMenu = $('record-type-menu');
var selectedType =
recordTypeMenu.options[recordTypeMenu.selectedIndex].value;
var recordData = {};
if (selectedType == 'text') {
recordData.type = 'TEXT';
if ($('text-form-text').value)
recordData.text = $('text-form-text').value;
if ($('text-form-encoding').value)
recordData.encoding = $('text-form-encoding').value;
if ($('text-form-language-code').value)
recordData.languageCode = $('text-form-language-code').value;
} else if (selectedType == 'uri') {
recordData.type = 'URI';
if ($('uri-form-uri').value)
recordData.uri = $('uri-form-uri').value;
if ($('uri-form-mime-type').value)
recordData.mimeType = $('uri-form-mime-type').value;
if ($('uri-form-target-size').value) {
var targetSize = $('uri-form-target-size').value;
targetSize = parseFloat(targetSize);
recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize;
}
} else if (selectedType == 'smart-poster') {
recordData.type = 'SMART_POSTER';
if ($('smart-poster-form-uri').value)
recordData.uri = $('smart-poster-form-uri').value;
if ($('smart-poster-form-mime-type').value)
recordData.mimeType = $('smart-poster-form-mime-type').value;
if ($('smart-poster-form-target-size').value) {
var targetSize = $('smart-poster-form-target-size').value;
targetSize = parseFloat(targetSize);
recordData.targetSize = isNaN(targetSize) ? 0.0 : targetSize;
}
var title = {};
if ($('smart-poster-form-title-text').value)
title.text = $('smart-poster-form-title-text').value;
if ($('smart-poster-form-title-encoding').value)
title.encoding = $('smart-poster-form-title-encoding').value;
if ($('smart-poster-form-title-language-code').value)
title.languageCode =
$('smart-poster-form-title-language-code').value;
if (Object.keys(title).length != 0)
recordData.titles = [title];
}
chrome.send('submitRecordForm', [recordData]);
},
/**
* Given a dictionary |data|, builds a table where each row contains the
* a key and its value. The resulting table is then added as the sole child
* of |div|. |data| contains information about an adapter, tag, or peer and
* this method creates a table for display, thus the value of some keys
* will be processed.
*
* @param {DOMElement} div The container that the table should be rendered
* to.
* @param {dictionary} data Data to generate the table from.
*/
createTableFromData: function(div, data) {
div.textContent = '';
var table = document.createElement('table');
table.classList.add('parameters-table');
for (var key in data) {
var row = document.createElement('tr');
var col = document.createElement('td');
col.textContent = key;
row.appendChild(col);
col = document.createElement('td');
var value = data[key];
if (key == 'records')
value = value.length;
else if (key == 'supportedTechnologies')
value = value.join(', ');
col.textContent = value;
row.appendChild(col);
table.appendChild(row);
}
div.appendChild(table);
},
};
cr.addSingletonGetter(NfcDebugUI);
/**
* Initializes the page after the content has loaded.
*/
NfcDebugUI.initialize = function() {
$('nfc-adapter-info').hidden = true;
$('adapter-toggles').hidden = true;
$('nfc-adapter-info').classList.add('transition-out');
$('ndef-record-form').classList.add('transition-out');
$('nfc-peer-info').classList.add('transition-out');
$('nfc-tag-info').classList.add('transition-out');
$('power-toggle').onclick = function() {
NfcDebugUI.getInstance().toggleAdapterPower();
};
$('poll-toggle').onclick = function() {
NfcDebugUI.getInstance().toggleAdapterPolling();
};
$('record-type-menu').onchange = function() {
NfcDebugUI.getInstance().recordTypeChanged();
};
$('record-form-submit-button').onclick = function() {
NfcDebugUI.getInstance().submitRecordForm();
};
$('record-form-submit-button').hidden = true;
NfcDebugUI.getInstance().updateRecordFormContents();
chrome.send('initialize');
};
/**
* Updates the UI based on the NFC availability on the current platform.
*
* @param {bool} available If true, NFC is supported on the current platform.
*/
NfcDebugUI.onNfcAvailabilityDetermined = function(available) {
$('nfc-not-supported').hidden = available;
};
/**
* Notifies the UI that information about the NFC adapter has been received.
*
* @param {dictionary} data Properties of the NFC adapter.
*/
NfcDebugUI.onNfcAdapterInfoChanged = function(data) {
NfcDebugUI.getInstance().setAdapterData(data);
$('nfc-adapter-info').hidden = false;
NfcDebugUI.getInstance().createTableFromData($('adapter-parameters'), data);
$('nfc-adapter-info').classList.toggle('transition-out', !data.present);
$('nfc-adapter-info').classList.toggle('transition-in', data.present);
$('ndef-record-form').classList.toggle('transition-out', !data.present);
$('ndef-record-form').classList.toggle('transition-in', data.present);
$('adapter-toggles').hidden = !data.present;
$('ndef-record-form').hidden = !data.present;
$('power-toggle').textContent = loadTimeData.getString(
data.powered ? 'adapterPowerOffText' : 'adapterPowerOnText');
$('poll-toggle').textContent = loadTimeData.getString(
data.polling ? 'adapterStopPollText' : 'adapterStartPollText');
};
/**
* Notifies the UI that information about an NFC peer has been received.
*
* @param {dictionary} data Properties of the NFC peer device.
*/
NfcDebugUI.onNfcPeerDeviceInfoChanged = function(data) {
NfcDebugUI.getInstance().setPeerData(data);
if (Object.keys(data).length == 0) {
$('nfc-peer-info').classList.add('transition-out');
$('nfc-peer-info').classList.remove('transition-in');
$('record-form-submit-button').hidden = true;
return;
}
$('nfc-peer-info').classList.remove('transition-out');
$('nfc-peer-info').classList.add('transition-in');
NfcDebugUI.getInstance().createTableFromData($('peer-parameters'), data);
$('record-form-submit-button').hidden = false;
$('record-form-submit-button').textContent =
loadTimeData.getString('ndefFormPushButtonText');
if (data.records.length == 0) {
$('peer-records-entry').hidden = true;
return;
}
$('peer-records-entry').hidden = false;
NfcDebugUI.getInstance().renderRecords($('peer-records-container'),
data.records);
};
/**
* Notifies the UI that information about an NFC tag has been received.
*
* @param {dictionary} data Properties of the NFC tag.
*/
NfcDebugUI.onNfcTagInfoChanged = function(data) {
NfcDebugUI.getInstance().setTagData(data);
if (Object.keys(data).length == 0) {
$('nfc-tag-info').classList.add('transition-out');
$('nfc-tag-info').classList.remove('transition-in');
$('record-form-submit-button').hidden = true;
return;
}
$('nfc-tag-info').classList.remove('transition-out');
$('nfc-tag-info').classList.add('transition-in');
NfcDebugUI.getInstance().createTableFromData($('tag-parameters'), data);
$('record-form-submit-button').hidden = false;
$('record-form-submit-button').textContent =
loadTimeData.getString('ndefFormWriteButtonText');
if (data.records.length == 0) {
$('tag-records-entry').hidden = true;
return;
}
$('tag-records-entry').hidden = false;
NfcDebugUI.getInstance().renderRecords($('tag-records-container'),
data.records);
};
/**
* Notifies the UI that a call to "setAdapterPower" failed. Displays an
* alert.
*/
NfcDebugUI.onSetAdapterPowerFailed = function() {
alert(loadTimeData.getString('errorFailedToSetPowerText'));
};
/**
* Notifies the UI that a call to "setAdapterPolling" failed. Displays an
* alert.
*/
NfcDebugUI.onSetAdapterPollingFailed = function() {
alert(loadTimeData.getString('errorFailedToSetPollingText'));
};
/**
* Notifies the UI that an error occurred while submitting an NDEF record
* form.
* @param {string} errorMessage An error message, describing the failure.
*/
NfcDebugUI.onSubmitRecordFormFailed = function(errorMessage) {
alert(loadTimeData.getString('errorFailedToSubmitPrefixText') +
' ' + errorMessage);
};
// Export
return {
NfcDebugUI: NfcDebugUI
};
});
document.addEventListener('DOMContentLoaded', nfcDebug.NfcDebugUI.initialize);

@ -168,7 +168,6 @@ split_static_library("ui") {
"//content/public/common",
"//crypto",
"//device/core",
"//device/nfc",
"//device/usb",
"//media",
"//net:net_with_v8",

@ -7,7 +7,6 @@ include_rules = [
"+components/sync/base/weak_handle.h",
"+components/sync/js",
"+device/bluetooth",
"+device/nfc",
# Generated files
"+js2webui/chrome/test/data",

@ -134,7 +134,6 @@
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h"
#include "chrome/browser/ui/webui/chromeos/network_ui.h"
#include "chrome/browser/ui/webui/chromeos/nfc_debug_ui.h"
#include "chrome/browser/ui/webui/chromeos/power_ui.h"
#include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h"
#include "chrome/browser/ui/webui/chromeos/set_time_ui.h"
@ -481,8 +480,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
return &NewWebUI<MobileSetupUI>;
if (url.host() == chrome::kChromeUINetworkHost)
return &NewWebUI<chromeos::NetworkUI>;
if (url.host() == chrome::kChromeUINfcDebugHost)
return &NewWebUI<chromeos::NfcDebugUI>;
if (url.host() == chrome::kChromeUIOobeHost)
return &NewWebUI<chromeos::OobeUI>;
if (url.host() == chrome::kChromeUIPowerHost)

@ -1,744 +0,0 @@
// Copyright 2014 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 "chrome/browser/ui/webui/chromeos/nfc_debug_ui.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "device/nfc/nfc_adapter.h"
#include "device/nfc/nfc_adapter_factory.h"
#include "device/nfc/nfc_peer.h"
#include "device/nfc/nfc_tag.h"
using device::NfcAdapter;
using device::NfcAdapterFactory;
using device::NfcNdefMessage;
using device::NfcNdefRecord;
using device::NfcNdefTagTechnology;
using device::NfcPeer;
using device::NfcTag;
using device::NfcTagTechnology;
namespace chromeos {
namespace {
// Keys for various NFC properties that are used by JS.
const char kAdapterPeersProperty[] = "peers";
const char kAdapterPollingProperty[] = "polling";
const char kAdapterPoweredProperty[] = "powered";
const char kAdapterPresentProperty[] = "present";
const char kAdapterTagsProperty[] = "tags";
const char kPeerIdentifierProperty[] = "identifier";
const char kPeerRecordsProperty[] = "records";
const char kTagIdentifierProperty[] = "identifier";
const char kTagTypeProperty[] = "type";
const char kTagReadOnlyProperty[] = "readOnly";
const char kTagRecordsProperty[] = "records";
const char kTagSupportedProtocolProperty[] = "supportedProtocol";
const char kTagSupportedTechnologiesProperty[] = "supportedTechnologies";
const char kRecordTypeProperty[] = "type";
// Tag types.
const char kTagType1[] = "TYPE-1";
const char kTagType2[] = "TYPE-2";
const char kTagType3[] = "TYPE-3";
const char kTagType4[] = "TYPE-4";
const char kTagTypeUnknown[] = "UNKNOWN";
// NFC transfer protocols.
const char kTagProtocolFelica[] = "FELICA";
const char kTagProtocolIsoDep[] = "ISO-DEP";
const char kTagProtocolJewel[] = "JEWEL";
const char kTagProtocolMifare[] = "MIFARE";
const char kTagProtocolNfcDep[] = "NFC-DEP";
const char kTagProtocolUnknown[] = "UNKNOWN";
// NFC tag technologies.
const char kTagTechnologyNfcA[] = "NFC-A";
const char kTagTechnologyNfcB[] = "NFC-B";
const char kTagTechnologyNfcF[] = "NFC-F";
const char kTagTechnologyNfcV[] = "NFC-V";
const char kTagTechnologyIsoDep[] = "ISO-DEP";
const char kTagTechnologyNdef[] = "NDEF";
// NDEF types.
const char kTypeHandoverCarrier[] = "HANDOVER_CARRIER";
const char kTypeHandoverRequest[] = "HANDOVER_REQUEST";
const char kTypeHandoverSelect[] = "HANDOVER_SELECT";
const char kTypeSmartPoster[] = "SMART_POSTER";
const char kTypeText[] = "TEXT";
const char kTypeURI[] = "URI";
const char kTypeUnknown[] = "UNKNOWN";
// JavaScript callback constants.
const char kInitializeCallback[] = "initialize";
const char kSetAdapterPowerCallback[] = "setAdapterPower";
const char kSetAdapterPollingCallback[] = "setAdapterPolling";
const char kSubmitRecordFormCallback[] = "submitRecordForm";
// Constants for JavaScript functions that we can call.
const char kOnNfcAdapterInfoChangedFunction[] =
"nfcDebug.NfcDebugUI.onNfcAdapterInfoChanged";
const char kOnNfcAvailabilityDeterminedFunction[] =
"nfcDebug.NfcDebugUI.onNfcAvailabilityDetermined";
const char kOnNfcPeerDeviceInfoChangedFunction[] =
"nfcDebug.NfcDebugUI.onNfcPeerDeviceInfoChanged";
const char kOnNfcTagInfoChangedFunction[] =
"nfcDebug.NfcDebugUI.onNfcTagInfoChanged";
const char kOnSetAdapterPollingFailedFunction[] =
"nfcDebug.NfcDebugUI.onSetAdapterPollingFailed";
const char kOnSetAdapterPowerFailedFunction[] =
"nfcDebug.NfcDebugUI.onSetAdapterPowerFailed";
const char kOnSubmitRecordFormFailedFunction[] =
"nfcDebug.NfcDebugUI.onSubmitRecordFormFailed";
std::string RecordTypeToString(NfcNdefRecord::Type type) {
switch (type) {
case NfcNdefRecord::kTypeHandoverCarrier:
return kTypeHandoverCarrier;
case NfcNdefRecord::kTypeHandoverRequest:
return kTypeHandoverRequest;
case NfcNdefRecord::kTypeHandoverSelect:
return kTypeHandoverSelect;
case NfcNdefRecord::kTypeSmartPoster:
return kTypeSmartPoster;
case NfcNdefRecord::kTypeText:
return kTypeText;
case NfcNdefRecord::kTypeURI:
return kTypeURI;
case NfcNdefRecord::kTypeUnknown:
return kTypeUnknown;
}
return kTypeUnknown;
}
NfcNdefRecord::Type RecordTypeStringValueToEnum(const std::string& type) {
if (type == kTypeHandoverCarrier)
return NfcNdefRecord::kTypeHandoverCarrier;
if (type == kTypeHandoverRequest)
return NfcNdefRecord::kTypeHandoverRequest;
if (type == kTypeHandoverSelect)
return NfcNdefRecord::kTypeHandoverSelect;
if (type == kTypeSmartPoster)
return NfcNdefRecord::kTypeSmartPoster;
if (type == kTypeText)
return NfcNdefRecord::kTypeText;
if (type == kTypeURI)
return NfcNdefRecord::kTypeURI;
return NfcNdefRecord::kTypeUnknown;
}
std::string TagTypeToString(NfcTag::TagType type) {
switch (type) {
case NfcTag::kTagType1:
return kTagType1;
case NfcTag::kTagType2:
return kTagType2;
case NfcTag::kTagType3:
return kTagType3;
case NfcTag::kTagType4:
return kTagType4;
case NfcTag::kTagTypeUnknown:
return kTagTypeUnknown;
}
return kTagTypeUnknown;
}
std::string TagProtocolToString(NfcTag::Protocol protocol) {
switch (protocol) {
case NfcTag::kProtocolFelica:
return kTagProtocolFelica;
case NfcTag::kProtocolIsoDep:
return kTagProtocolIsoDep;
case NfcTag::kProtocolJewel:
return kTagProtocolJewel;
case NfcTag::kProtocolMifare:
return kTagProtocolMifare;
case NfcTag::kProtocolNfcDep:
return kTagProtocolNfcDep;
case NfcTag::kProtocolUnknown:
return kTagProtocolUnknown;
}
return kTagProtocolUnknown;
}
// content::WebUIMessageHandler implementation for this page.
class NfcDebugMessageHandler : public content::WebUIMessageHandler,
public NfcAdapter::Observer,
public NfcNdefTagTechnology::Observer,
public NfcPeer::Observer,
public NfcTag::Observer {
public:
NfcDebugMessageHandler();
~NfcDebugMessageHandler() override;
// WebUIMessageHandler implementation.
void RegisterMessages() override;
// NfcAdapter::Observer overrides.
void AdapterPresentChanged(NfcAdapter* adapter, bool present) override;
void AdapterPoweredChanged(NfcAdapter* adapter, bool powered) override;
void AdapterPollingChanged(NfcAdapter* adapter, bool polling) override;
void TagFound(NfcAdapter* adapter, NfcTag* tag) override;
void TagLost(NfcAdapter* adapter, NfcTag* tag) override;
void PeerFound(NfcAdapter* adaper, NfcPeer* peer) override;
void PeerLost(NfcAdapter* adapter, NfcPeer* peer) override;
// NfcNdefTagTechnology::Observer override.
void RecordReceived(NfcTag* tag, const NfcNdefRecord* record) override;
// NfcPeer::Observer override.
void RecordReceived(NfcPeer* peer, const NfcNdefRecord* record) override;
// NfcTag::Observer override.
void TagReady(NfcTag* tag) override;
private:
// Called by the UI when the page loads. This method requests information
// about NFC availability on the current platform and requests the underlying
// Adapter object. The UI is notified once the information is available.
void Initialize(const base::ListValue* args);
// Called by the UI to toggle the adapter power. |args| will contain one
// boolean that indicates whether the power should be set to ON or OFF.
void SetAdapterPower(const base::ListValue* args);
void OnSetAdapterPowerError();
// Called by the UI set the adapter's poll status. |args| will contain one
// boolean that indicates whether polling should be started or stopped.
void SetAdapterPolling(const base::ListValue* args);
void OnSetAdapterPollingError();
// Called by the UI to push an NDEF record to a remote device or tag. |args|
// will contain one dictionary that contains the record data.
void SubmitRecordForm(const base::ListValue* args);
void OnSubmitRecordFormFailed(const std::string& error_message);
// Callback passed to NfcAdapterFactory::GetAdapter.
void OnGetAdapter(scoped_refptr<NfcAdapter> adapter);
// Stores the properties of the NFC adapter in |out|, mapping these to keys
// that will be read by JS.
void GetAdapterProperties(base::DictionaryValue* out);
// Stores the properties of the NFC peer in |out|, mapping these to keys
// that will be read by JS. |out| will not be modified, if no peer is known.
void GetPeerProperties(base::DictionaryValue* out);
// Stores the properties of the NFC tag in |out|, mapping these to keys
// that will be read by JS. |out| will not be modified, if no tag is known.
void GetTagProperties(base::DictionaryValue* out);
// Returns the records in |message| by populating |out|, in which
// they have been converted to a JS friendly format.
void GetRecordList(const NfcNdefMessage& message, base::ListValue* out);
// Updates the data displayed in the UI for the current adapter.
void UpdateAdapterInfo();
// Updates the data displayed in the UI for the current peer.
void UpdatePeerInfo();
// Updates the data displayed in the UI for the current tag.
void UpdateTagInfo();
// The NfcAdapter object.
scoped_refptr<NfcAdapter> nfc_adapter_;
// The cached identifier of the most recent NFC peer device found.
std::string peer_identifier_;
// The cached identifier of the most recent NFC tag found.
std::string tag_identifier_;
DISALLOW_COPY_AND_ASSIGN(NfcDebugMessageHandler);
};
NfcDebugMessageHandler::NfcDebugMessageHandler() {
}
NfcDebugMessageHandler::~NfcDebugMessageHandler() {
if (!nfc_adapter_.get())
return;
nfc_adapter_->RemoveObserver(this);
if (!peer_identifier_.empty()) {
NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_);
if (peer)
peer->RemoveObserver(this);
}
if (!tag_identifier_.empty()) {
NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_);
if (tag)
tag->RemoveObserver(this);
}
}
void NfcDebugMessageHandler::AdapterPresentChanged(
NfcAdapter* adapter,
bool present) {
UpdateAdapterInfo();
}
void NfcDebugMessageHandler::AdapterPoweredChanged(
NfcAdapter* adapter,
bool powered) {
UpdateAdapterInfo();
}
void NfcDebugMessageHandler::AdapterPollingChanged(
NfcAdapter* adapter,
bool polling) {
UpdateAdapterInfo();
}
void NfcDebugMessageHandler::TagFound(NfcAdapter* adapter, NfcTag* tag) {
VLOG(1) << "Found NFC tag: " << tag->GetIdentifier();
tag->AddObserver(this);
tag_identifier_ = tag->GetIdentifier();
tag->GetNdefTagTechnology()->AddObserver(this);
UpdateAdapterInfo();
UpdateTagInfo();
}
void NfcDebugMessageHandler::TagLost(NfcAdapter*adapter, NfcTag* tag) {
VLOG(1) << "Lost NFC tag: " << tag->GetIdentifier();
tag->RemoveObserver(this);
tag->GetNdefTagTechnology()->RemoveObserver(this);
tag_identifier_.clear();
UpdateAdapterInfo();
UpdateTagInfo();
}
void NfcDebugMessageHandler::PeerFound(NfcAdapter* adaper, NfcPeer* peer) {
VLOG(1) << "Found NFC peer device: " << peer->GetIdentifier();
peer->AddObserver(this);
peer_identifier_ = peer->GetIdentifier();
UpdateAdapterInfo();
UpdatePeerInfo();
}
void NfcDebugMessageHandler::PeerLost(NfcAdapter* adapter, NfcPeer* peer) {
VLOG(1) << "Lost NFC peer device: " << peer->GetIdentifier();
peer->RemoveObserver(this);
peer_identifier_.clear();
UpdateAdapterInfo();
UpdatePeerInfo();
}
void NfcDebugMessageHandler::RecordReceived(
NfcTag* tag,
const NfcNdefRecord* record) {
if (tag->GetIdentifier() != tag_identifier_) {
LOG(WARNING) << "Records received from unknown tag: "
<< tag->GetIdentifier();
return;
}
UpdateTagInfo();
}
void NfcDebugMessageHandler::RecordReceived(
NfcPeer* peer,
const NfcNdefRecord* record) {
if (peer->GetIdentifier() != peer_identifier_) {
LOG(WARNING) << "Records received from unknown peer: "
<< peer->GetIdentifier();
return;
}
UpdatePeerInfo();
}
void NfcDebugMessageHandler::TagReady(NfcTag* tag) {
if (tag_identifier_ != tag->GetIdentifier()) {
LOG(WARNING) << "Unknown tag became ready: " << tag->GetIdentifier();
return;
}
VLOG(1) << "Tag ready: " << tag->GetIdentifier();
UpdateTagInfo();
}
void NfcDebugMessageHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
kInitializeCallback,
base::Bind(&NfcDebugMessageHandler::Initialize,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
kSetAdapterPowerCallback,
base::Bind(&NfcDebugMessageHandler::SetAdapterPower,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
kSetAdapterPollingCallback,
base::Bind(&NfcDebugMessageHandler::SetAdapterPolling,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(
kSubmitRecordFormCallback,
base::Bind(&NfcDebugMessageHandler::SubmitRecordForm,
base::Unretained(this)));
}
void NfcDebugMessageHandler::Initialize(const base::ListValue* args) {
bool nfc_available = NfcAdapterFactory::IsNfcAvailable();
base::FundamentalValue available(nfc_available);
web_ui()->CallJavascriptFunctionUnsafe(kOnNfcAvailabilityDeterminedFunction,
available);
if (!nfc_available) {
LOG(WARNING) << "NFC is not available on current platform.";
return;
}
NfcAdapterFactory::GetAdapter(
base::Bind(&NfcDebugMessageHandler::OnGetAdapter,
base::Unretained(this)));
}
void NfcDebugMessageHandler::SetAdapterPower(const base::ListValue* args) {
DCHECK(1 == args->GetSize());
DCHECK(nfc_adapter_.get());
bool powered;
args->GetBoolean(0, &powered);
VLOG(1) << "Setting adapter power: " << powered;
nfc_adapter_->SetPowered(
powered, base::Bind(&base::DoNothing),
base::Bind(&NfcDebugMessageHandler::OnSetAdapterPowerError,
base::Unretained(this)));
}
void NfcDebugMessageHandler::OnSetAdapterPowerError() {
LOG(ERROR) << "Failed to set NFC adapter power.";
web_ui()->CallJavascriptFunctionUnsafe(kOnSetAdapterPowerFailedFunction);
}
void NfcDebugMessageHandler::SetAdapterPolling(const base::ListValue* args) {
DCHECK(1 == args->GetSize());
DCHECK(nfc_adapter_.get());
bool start = false;
bool result = args->GetBoolean(0, &start);
DCHECK(result);
if (start) {
VLOG(1) << "Starting NFC poll loop.";
nfc_adapter_->StartPolling(
base::Bind(&base::DoNothing),
base::Bind(&NfcDebugMessageHandler::OnSetAdapterPollingError,
base::Unretained(this)));
} else {
VLOG(1) << "Stopping NFC poll loop.";
nfc_adapter_->StopPolling(
base::Bind(&base::DoNothing),
base::Bind(&NfcDebugMessageHandler::OnSetAdapterPollingError,
base::Unretained(this)));
}
}
void NfcDebugMessageHandler::OnSetAdapterPollingError() {
LOG(ERROR) << "Failed to start/stop polling.";
web_ui()->CallJavascriptFunctionUnsafe(kOnSetAdapterPollingFailedFunction);
}
void NfcDebugMessageHandler::SubmitRecordForm(const base::ListValue* args) {
DCHECK(1 == args->GetSize());
DCHECK(nfc_adapter_.get());
const base::DictionaryValue* record_data_const = NULL;
if (!args->GetDictionary(0, &record_data_const)) {
NOTREACHED();
return;
}
if (peer_identifier_.empty() && tag_identifier_.empty()) {
OnSubmitRecordFormFailed("No peer or tag present.");
return;
}
std::string type;
if (!record_data_const->GetString(kRecordTypeProperty, &type)) {
OnSubmitRecordFormFailed("Record type not provided.");
return;
}
base::DictionaryValue* record_data = record_data_const->DeepCopy();
record_data->Remove(kRecordTypeProperty, NULL);
// Convert the "targetSize" field to a double, in case JS stored it as an
// integer.
int target_size;
if (record_data->GetInteger(NfcNdefRecord::kFieldTargetSize, &target_size)) {
record_data->SetDouble(NfcNdefRecord::kFieldTargetSize,
static_cast<double>(target_size));
}
NfcNdefRecord record;
if (!record.Populate(RecordTypeStringValueToEnum(type), record_data)) {
OnSubmitRecordFormFailed("Invalid record data provided. Missing required "
"fields?");
return;
}
if (!peer_identifier_.empty()) {
NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_);
if (!peer) {
OnSubmitRecordFormFailed("The current NFC adapter doesn't seem to know "
"about peer: " + peer_identifier_);
return;
}
NfcNdefMessage message;
message.AddRecord(&record);
peer->PushNdef(message,
base::Bind(&base::DoNothing),
base::Bind(&NfcDebugMessageHandler::OnSubmitRecordFormFailed,
base::Unretained(this),
"Failed to push NDEF record."));
return;
}
NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_);
if (!tag) {
OnSubmitRecordFormFailed("The current NFC tag doesn't seem to known about "
"tag: " + tag_identifier_);
return;
}
NfcNdefMessage message;
message.AddRecord(&record);
tag->GetNdefTagTechnology()->WriteNdef(
message,
base::Bind(&base::DoNothing),
base::Bind(&NfcDebugMessageHandler::OnSubmitRecordFormFailed,
base::Unretained(this),
"Failed to write NDEF record."));
}
void NfcDebugMessageHandler::OnSubmitRecordFormFailed(
const std::string& error_message) {
LOG(ERROR) << "SubmitRecordForm failed: " << error_message;
web_ui()->CallJavascriptFunctionUnsafe(kOnSubmitRecordFormFailedFunction,
base::StringValue(error_message));
}
void NfcDebugMessageHandler::OnGetAdapter(
scoped_refptr<NfcAdapter> adapter) {
if (nfc_adapter_.get())
return;
nfc_adapter_ = adapter;
nfc_adapter_->AddObserver(this);
UpdateAdapterInfo();
NfcAdapter::PeerList peers;
nfc_adapter_->GetPeers(&peers);
for (NfcAdapter::PeerList::const_iterator iter = peers.begin();
iter != peers.end(); ++iter) {
PeerFound(nfc_adapter_.get(), *iter);
}
NfcAdapter::TagList tags;
nfc_adapter_->GetTags(&tags);
for (NfcAdapter::TagList::const_iterator iter = tags.begin();
iter != tags.end(); ++iter) {
TagFound(nfc_adapter_.get(), *iter);
}
}
void NfcDebugMessageHandler::GetAdapterProperties(
base::DictionaryValue* out) {
if (!nfc_adapter_.get()) {
VLOG(1) << "NFC adapter hasn't been received yet.";
return;
}
out->SetBoolean(kAdapterPresentProperty, nfc_adapter_->IsPresent());
out->SetBoolean(kAdapterPollingProperty, nfc_adapter_->IsPolling());
out->SetBoolean(kAdapterPoweredProperty, nfc_adapter_->IsPowered());
NfcAdapter::PeerList peers;
nfc_adapter_->GetPeers(&peers);
out->SetInteger(kAdapterPeersProperty, static_cast<int>(peers.size()));
NfcAdapter::TagList tags;
nfc_adapter_->GetTags(&tags);
out->SetInteger(kAdapterTagsProperty, static_cast<int>(tags.size()));
}
void NfcDebugMessageHandler::GetPeerProperties(base::DictionaryValue* out) {
if (peer_identifier_.empty()) {
VLOG(1) << "No known peer exists.";
return;
}
if (!nfc_adapter_.get()) {
VLOG(1) << "NFC adapter hasn't been received yet.";
return;
}
NfcPeer* peer = nfc_adapter_->GetPeer(peer_identifier_);
if (!peer) {
LOG(ERROR) << "The current NFC adapter doesn't seem to know about peer: "
<< peer_identifier_;
return;
}
out->SetString(kPeerIdentifierProperty, peer_identifier_);
base::ListValue* records = new base::ListValue();
GetRecordList(peer->GetNdefMessage(), records);
out->Set(kPeerRecordsProperty, records);
}
void NfcDebugMessageHandler::GetTagProperties(base::DictionaryValue* out) {
if (tag_identifier_.empty()) {
VLOG(1) << "No known tag exists.";
return;
}
if (!nfc_adapter_.get()) {
VLOG(1) << "NFC adapter hasn't been received yet.";
return;
}
NfcTag* tag = nfc_adapter_->GetTag(tag_identifier_);
if (!tag) {
LOG(ERROR) << "The current NFC adapter doesn't seem to know about tag: "
<< tag_identifier_;
return;
}
out->SetString(kTagIdentifierProperty, tag_identifier_);
out->SetString(kTagTypeProperty, TagTypeToString(tag->GetType()));
out->SetBoolean(kTagReadOnlyProperty, tag->IsReadOnly());
out->SetString(kTagSupportedProtocolProperty,
TagProtocolToString(tag->GetSupportedProtocol()));
base::ListValue* technologies = new base::ListValue();
NfcTagTechnology::TechnologyTypeMask technology_mask =
tag->GetSupportedTechnologies();
if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcA)
technologies->AppendString(kTagTechnologyNfcA);
if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcB)
technologies->AppendString(kTagTechnologyNfcB);
if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcF)
technologies->AppendString(kTagTechnologyNfcF);
if (technology_mask & NfcTagTechnology::kTechnologyTypeNfcV)
technologies->AppendString(kTagTechnologyNfcV);
if (technology_mask & NfcTagTechnology::kTechnologyTypeIsoDep)
technologies->AppendString(kTagTechnologyIsoDep);
if (technology_mask & NfcTagTechnology::kTechnologyTypeNdef)
technologies->AppendString(kTagTechnologyNdef);
out->Set(kTagSupportedTechnologiesProperty, technologies);
base::ListValue* records = new base::ListValue();
GetRecordList(tag->GetNdefTagTechnology()->GetNdefMessage(), records);
out->Set(kTagRecordsProperty, records);
}
void NfcDebugMessageHandler::GetRecordList(const NfcNdefMessage& message,
base::ListValue* out) {
for (NfcNdefMessage::RecordList::const_iterator iter =
message.records().begin();
iter != message.records().end(); ++iter) {
const NfcNdefRecord* record = (*iter);
base::DictionaryValue* record_data = record->data().DeepCopy();
record_data->SetString(kRecordTypeProperty,
RecordTypeToString(record->type()));
out->Append(record_data);
}
}
void NfcDebugMessageHandler::UpdateAdapterInfo() {
base::DictionaryValue data;
GetAdapterProperties(&data);
web_ui()->CallJavascriptFunctionUnsafe(kOnNfcAdapterInfoChangedFunction,
data);
}
void NfcDebugMessageHandler::UpdatePeerInfo() {
base::DictionaryValue data;
GetPeerProperties(&data);
web_ui()->CallJavascriptFunctionUnsafe(kOnNfcPeerDeviceInfoChangedFunction,
data);
}
void NfcDebugMessageHandler::UpdateTagInfo() {
base::DictionaryValue data;
GetTagProperties(&data);
web_ui()->CallJavascriptFunctionUnsafe(kOnNfcTagInfoChangedFunction, data);
}
} // namespace
NfcDebugUI::NfcDebugUI(content::WebUI* web_ui)
: content::WebUIController(web_ui) {
web_ui->AddMessageHandler(new NfcDebugMessageHandler());
content::WebUIDataSource* html_source =
content::WebUIDataSource::Create(chrome::kChromeUINfcDebugHost);
html_source->AddLocalizedString("titleText", IDS_NFC_DEBUG_TITLE);
html_source->AddLocalizedString("notSupportedText",
IDS_NFC_DEBUG_NOT_SUPPORTED);
html_source->AddLocalizedString("adapterHeaderText",
IDS_NFC_DEBUG_ADAPTER_HEADER);
html_source->AddLocalizedString("adapterPowerOnText",
IDS_NFC_DEBUG_ADAPTER_POWER_ON);
html_source->AddLocalizedString("adapterPowerOffText",
IDS_NFC_DEBUG_ADAPTER_POWER_OFF);
html_source->AddLocalizedString("adapterStartPollText",
IDS_NFC_DEBUG_ADAPTER_START_POLL);
html_source->AddLocalizedString("adapterStopPollText",
IDS_NFC_DEBUG_ADAPTER_STOP_POLL);
html_source->AddLocalizedString("ndefFormHeaderText",
IDS_NFC_DEBUG_NDEF_FORM_HEADER);
html_source->AddLocalizedString("ndefFormTypeTextText",
IDS_NFC_DEBUG_NDEF_FORM_TYPE_TEXT);
html_source->AddLocalizedString("ndefFormTypeUriText",
IDS_NFC_DEBUG_NDEF_FORM_TYPE_URI);
html_source->AddLocalizedString("ndefFormTypeSmartPosterText",
IDS_NFC_DEBUG_NDEF_FORM_TYPE_SMART_POSTER);
html_source->AddLocalizedString("ndefFormWriteButtonText",
IDS_NFC_DEBUG_NDEF_FORM_WRITE_BUTTON);
html_source->AddLocalizedString("ndefFormFieldTextText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_TEXT);
html_source->AddLocalizedString("ndefFormFieldEncodingText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_ENCODING);
html_source->AddLocalizedString("ndefFormFieldLanguageCodeText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_LANGUAGE_CODE);
html_source->AddLocalizedString("ndefFormFieldUriText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_URI);
html_source->AddLocalizedString("ndefFormFieldMimeTypeText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_MIME_TYPE);
html_source->AddLocalizedString("ndefFormFieldTargetSizeText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_TARGET_SIZE);
html_source->AddLocalizedString("ndefFormFieldTitleTextText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_TEXT);
html_source->AddLocalizedString("ndefFormFieldTitleEncodingText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_ENCODING);
html_source->AddLocalizedString(
"ndefFormFieldTitleLanguageCodeText",
IDS_NFC_DEBUG_NDEF_FORM_FIELD_TITLE_LANGUAGE_CODE);
html_source->AddLocalizedString("ndefFormPushButtonText",
IDS_NFC_DEBUG_NDEF_FORM_PUSH_BUTTON);
html_source->AddLocalizedString("nfcPeerHeaderText",
IDS_NFC_DEBUG_NFC_PEER_HEADER);
html_source->AddLocalizedString("nfcTagHeaderText",
IDS_NFC_DEBUG_NFC_TAG_HEADER);
html_source->AddLocalizedString("recordsHeaderText",
IDS_NFC_DEBUG_RECORDS_HEADER);
html_source->AddLocalizedString("errorFailedToSetPowerText",
IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POWER);
html_source->AddLocalizedString("errorFailedToSetPollingText",
IDS_NFC_DEBUG_ERROR_FAILED_TO_SET_POLLING);
html_source->AddLocalizedString("errorFailedToSubmitPrefixText",
IDS_NFC_DEBUG_ERROR_FAILED_TO_SUBMIT_PREFIX);
html_source->SetJsonPath("strings.js");
// Add required resources.
html_source->AddResourcePath("nfc_debug.css", IDR_NFC_DEBUG_CSS);
html_source->AddResourcePath("nfc_debug.js", IDR_NFC_DEBUG_JS);
html_source->SetDefaultResource(IDR_NFC_DEBUG_HTML);
Profile* profile = Profile::FromWebUI(web_ui);
content::WebUIDataSource::Add(profile, html_source);
}
NfcDebugUI::~NfcDebugUI() {
}
} // namespace chromeos

@ -1,24 +0,0 @@
// Copyright 2014 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.
#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_NFC_DEBUG_UI_H_
#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_NFC_DEBUG_UI_H_
#include "base/macros.h"
#include "content/public/browser/web_ui_controller.h"
namespace chromeos {
class NfcDebugUI : public content::WebUIController {
public:
explicit NfcDebugUI(content::WebUI* web_ui);
~NfcDebugUI() override;
private:
DISALLOW_COPY_AND_ASSIGN(NfcDebugUI);
};
} // namespace chromeos
#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_NFC_DEBUG_UI_H_

@ -279,8 +279,6 @@
'browser/ui/webui/chromeos/mobile_setup_ui.h',
'browser/ui/webui/chromeos/network_ui.cc',
'browser/ui/webui/chromeos/network_ui.h',
'browser/ui/webui/chromeos/nfc_debug_ui.cc',
'browser/ui/webui/chromeos/nfc_debug_ui.h',
'browser/ui/webui/chromeos/power_ui.cc',
'browser/ui/webui/chromeos/power_ui.h',
'browser/ui/webui/chromeos/proxy_settings_ui.cc',
@ -2984,7 +2982,6 @@
'dependencies': [
'browser_chromeos',
'../components/components.gyp:proximity_auth_webui',
'../device/nfc/nfc.gyp:device_nfc',
'../ui/base/ime/ui_base_ime.gyp:ui_base_ime',
'../ui/chromeos/ui_chromeos.gyp:ui_chromeos',
'../ui/chromeos/ui_chromeos.gyp:ui_chromeos_resources',

@ -114,7 +114,6 @@ const char kChromeUIDeviceEmulatorURL[] = "chrome://device-emulator/";
const char kChromeUIFirstRunURL[] = "chrome://first-run/";
const char kChromeUIKeyboardOverlayURL[] = "chrome://keyboardoverlay/";
const char kChromeUIMobileSetupURL[] = "chrome://mobilesetup/";
const char kChromeUINfcDebugURL[] = "chrome://nfc-debug/";
const char kChromeUIOobeURL[] = "chrome://oobe/";
const char kChromeUIOSCreditsURL[] = "chrome://os-credits/";
const char kChromeUIProxySettingsURL[] = "chrome://proxy-settings/";
@ -285,7 +284,6 @@ const char kChromeUIKeyboardOverlayHost[] = "keyboardoverlay";
const char kChromeUILoginContainerHost[] = "login-container";
const char kChromeUILoginHost[] = "login";
const char kChromeUIMobileSetupHost[] = "mobilesetup";
const char kChromeUINfcDebugHost[] = "nfc-debug";
const char kChromeUINetworkHost[] = "network";
const char kChromeUIOobeHost[] = "oobe";
const char kChromeUIOSCreditsHost[] = "os-credits";

@ -104,7 +104,6 @@ extern const char kChromeUIDeviceEmulatorURL[];
extern const char kChromeUIFirstRunURL[];
extern const char kChromeUIKeyboardOverlayURL[];
extern const char kChromeUIMobileSetupURL[];
extern const char kChromeUINfcDebugURL[];
extern const char kChromeUIOobeURL[];
extern const char kChromeUIOSCreditsURL[];
extern const char kChromeUIProxySettingsURL[];
@ -269,7 +268,6 @@ extern const char kChromeUILoginContainerHost[];
extern const char kChromeUILoginHost[];
extern const char kChromeUIMobileSetupHost[];
extern const char kChromeUINetworkHost[];
extern const char kChromeUINfcDebugHost[];
extern const char kChromeUIOobeHost[];
extern const char kChromeUIOSCreditsHost[];
extern const char kChromeUIPowerHost[];

@ -126,16 +126,6 @@
'dbus/fake_lorgnette_manager_client.h',
'dbus/fake_modem_messaging_client.cc',
'dbus/fake_modem_messaging_client.h',
'dbus/fake_nfc_adapter_client.cc',
'dbus/fake_nfc_adapter_client.h',
'dbus/fake_nfc_device_client.cc',
'dbus/fake_nfc_device_client.h',
'dbus/fake_nfc_manager_client.cc',
'dbus/fake_nfc_manager_client.h',
'dbus/fake_nfc_record_client.cc',
'dbus/fake_nfc_record_client.h',
'dbus/fake_nfc_tag_client.cc',
'dbus/fake_nfc_tag_client.h',
'dbus/fake_permission_broker_client.cc',
'dbus/fake_permission_broker_client.h',
'dbus/fake_power_manager_client.cc',
@ -166,20 +156,6 @@
'dbus/lorgnette_manager_client.h',
'dbus/modem_messaging_client.cc',
'dbus/modem_messaging_client.h',
'dbus/nfc_adapter_client.cc',
'dbus/nfc_adapter_client.h',
'dbus/nfc_client_helpers.cc',
'dbus/nfc_client_helpers.h',
'dbus/nfc_device_client.cc',
'dbus/nfc_device_client.h',
'dbus/nfc_manager_client.cc',
'dbus/nfc_manager_client.h',
'dbus/nfc_property_set.cc',
'dbus/nfc_property_set.h',
'dbus/nfc_record_client.cc',
'dbus/nfc_record_client.h',
'dbus/nfc_tag_client.cc',
'dbus/nfc_tag_client.h',
'dbus/permission_broker_client.cc',
'dbus/permission_broker_client.h',
'dbus/pipe_reader.cc',
@ -438,7 +414,6 @@
'dbus/gsm_sms_client_unittest.cc',
'dbus/introspectable_client_unittest.cc',
'dbus/modem_messaging_client_unittest.cc',
'dbus/nfc_client_unittest.cc',
'dbus/power_policy_controller_unittest.cc',
'dbus/services/cros_dbus_service_unittest.cc',
'dbus/services/proxy_resolution_service_provider_unittest.cc',

@ -5,6 +5,7 @@ Older clients that have been removed:
* Amplifier (amplifier_client.cc)
* Audio DSP (audio_dsp_client.cc)
* NFC (nfc_manager_client.cc)
* peerd (peer_daemon_manager_client.cc)
* privetd (privet_daemon_manager_client.cc)
* Wi-Fi AP manager (ap_manager_client.cc)

@ -28,11 +28,6 @@
#include "chromeos/dbus/fake_introspectable_client.h"
#include "chromeos/dbus/fake_lorgnette_manager_client.h"
#include "chromeos/dbus/fake_modem_messaging_client.h"
#include "chromeos/dbus/fake_nfc_adapter_client.h"
#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_manager_client.h"
#include "chromeos/dbus/fake_nfc_record_client.h"
#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "chromeos/dbus/fake_permission_broker_client.h"
#include "chromeos/dbus/fake_shill_device_client.h"
#include "chromeos/dbus/fake_shill_ipconfig_client.h"
@ -47,11 +42,6 @@
#include "chromeos/dbus/introspectable_client.h"
#include "chromeos/dbus/lorgnette_manager_client.h"
#include "chromeos/dbus/modem_messaging_client.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "chromeos/dbus/permission_broker_client.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/power_policy_controller.h"
@ -87,7 +77,6 @@ const struct {
{ "image_burner", DBusClientBundle::IMAGE_BURNER },
{ "introspectable", DBusClientBundle::INTROSPECTABLE },
{ "modem_messaging", DBusClientBundle::MODEM_MESSAGING },
{ "nfc", DBusClientBundle::NFC },
{ "permission_broker", DBusClientBundle::PERMISSION_BROKER },
{ "power_manager", DBusClientBundle::POWER_MANAGER },
{ "session_manager", DBusClientBundle::SESSION_MANAGER },
@ -189,24 +178,6 @@ DBusClientBundle::DBusClientBundle(DBusClientTypeMask unstub_client_mask)
else
modem_messaging_client_.reset(new FakeModemMessagingClient);
// Create the NFC clients in the correct order based on their dependencies.
if (!IsUsingStub(NFC)) {
nfc_manager_client_.reset(NfcManagerClient::Create());
nfc_adapter_client_.reset(
NfcAdapterClient::Create(nfc_manager_client_.get()));
nfc_device_client_.reset(
NfcDeviceClient::Create(nfc_adapter_client_.get()));
nfc_tag_client_.reset(NfcTagClient::Create(nfc_adapter_client_.get()));
nfc_record_client_.reset(NfcRecordClient::Create(nfc_device_client_.get(),
nfc_tag_client_.get()));
} else {
nfc_manager_client_.reset(new FakeNfcManagerClient);
nfc_adapter_client_.reset(new FakeNfcAdapterClient);
nfc_device_client_.reset(new FakeNfcDeviceClient);
nfc_tag_client_.reset(new FakeNfcTagClient);
nfc_record_client_.reset(new FakeNfcRecordClient);
}
if (!IsUsingStub(PERMISSION_BROKER))
permission_broker_client_.reset(PermissionBrokerClient::Create());
else

@ -24,11 +24,6 @@ class ImageBurnerClient;
class IntrospectableClient;
class LorgnetteManagerClient;
class ModemMessagingClient;
class NfcAdapterClient;
class NfcDeviceClient;
class NfcManagerClient;
class NfcRecordClient;
class NfcTagClient;
class PermissionBrokerClient;
class PowerManagerClient;
class SMSClient;
@ -65,14 +60,13 @@ class CHROMEOS_EXPORT DBusClientBundle {
IMAGE_BURNER = 1 << 9,
INTROSPECTABLE = 1 << 10,
MODEM_MESSAGING = 1 << 11,
NFC = 1 << 12,
PERMISSION_BROKER = 1 << 13,
POWER_MANAGER = 1 << 14,
SESSION_MANAGER = 1 << 15,
SMS = 1 << 16,
SYSTEM_CLOCK = 1 << 17,
UPDATE_ENGINE = 1 << 18,
ARC_OBB_MOUNTER = 1 << 19,
PERMISSION_BROKER = 1 << 12,
POWER_MANAGER = 1 << 13,
SESSION_MANAGER = 1 << 14,
SMS = 1 << 15,
SYSTEM_CLOCK = 1 << 16,
UPDATE_ENGINE = 1 << 17,
ARC_OBB_MOUNTER = 1 << 18,
};
explicit DBusClientBundle(DBusClientTypeMask unstub_client_mask);
@ -159,26 +153,6 @@ class CHROMEOS_EXPORT DBusClientBundle {
return modem_messaging_client_.get();
}
NfcManagerClient* nfc_manager_client() {
return nfc_manager_client_.get();
}
NfcAdapterClient* nfc_adapter_client() {
return nfc_adapter_client_.get();
}
NfcDeviceClient* nfc_device_client() {
return nfc_device_client_.get();
}
NfcTagClient* nfc_tag_client() {
return nfc_tag_client_.get();
}
NfcRecordClient* nfc_record_client() {
return nfc_record_client_.get();
}
PermissionBrokerClient* permission_broker_client() {
return permission_broker_client_.get();
}
@ -228,13 +202,6 @@ class CHROMEOS_EXPORT DBusClientBundle {
std::unique_ptr<ImageBurnerClient> image_burner_client_;
std::unique_ptr<IntrospectableClient> introspectable_client_;
std::unique_ptr<ModemMessagingClient> modem_messaging_client_;
// The declaration order for NFC client objects is important. See
// DBusThreadManager::InitializeClients for the dependencies.
std::unique_ptr<NfcManagerClient> nfc_manager_client_;
std::unique_ptr<NfcAdapterClient> nfc_adapter_client_;
std::unique_ptr<NfcDeviceClient> nfc_device_client_;
std::unique_ptr<NfcTagClient> nfc_tag_client_;
std::unique_ptr<NfcRecordClient> nfc_record_client_;
std::unique_ptr<PermissionBrokerClient> permission_broker_client_;
std::unique_ptr<SystemClockClient> system_clock_client_;
std::unique_ptr<PowerManagerClient> power_manager_client_;

@ -23,11 +23,6 @@
#include "chromeos/dbus/introspectable_client.h"
#include "chromeos/dbus/lorgnette_manager_client.h"
#include "chromeos/dbus/modem_messaging_client.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "chromeos/dbus/permission_broker_client.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/session_manager_client.h"
@ -178,26 +173,6 @@ ModemMessagingClient* DBusThreadManager::GetModemMessagingClient() {
return client_bundle_->modem_messaging_client();
}
NfcAdapterClient* DBusThreadManager::GetNfcAdapterClient() {
return client_bundle_->nfc_adapter_client();
}
NfcDeviceClient* DBusThreadManager::GetNfcDeviceClient() {
return client_bundle_->nfc_device_client();
}
NfcManagerClient* DBusThreadManager::GetNfcManagerClient() {
return client_bundle_->nfc_manager_client();
}
NfcRecordClient* DBusThreadManager::GetNfcRecordClient() {
return client_bundle_->nfc_record_client();
}
NfcTagClient* DBusThreadManager::GetNfcTagClient() {
return client_bundle_->nfc_tag_client();
}
PermissionBrokerClient* DBusThreadManager::GetPermissionBrokerClient() {
return client_bundle_->permission_broker_client();
}
@ -247,15 +222,6 @@ void DBusThreadManager::InitializeClients() {
GetSystemClockClient()->Init(GetSystemBus());
GetUpdateEngineClient()->Init(GetSystemBus());
// Initialize the NFC clients in the correct order. The order of
// initialization matters due to dependencies that exist between the
// client objects.
GetNfcManagerClient()->Init(GetSystemBus());
GetNfcAdapterClient()->Init(GetSystemBus());
GetNfcDeviceClient()->Init(GetSystemBus());
GetNfcTagClient()->Init(GetSystemBus());
GetNfcRecordClient()->Init(GetSystemBus());
// This must be called after the list of clients so they've each had a
// chance to register with their object g_dbus_thread_managers.
if (GetSystemBus())
@ -463,35 +429,6 @@ void DBusThreadManagerSetter::SetModemMessagingClient(
std::move(client);
}
void DBusThreadManagerSetter::SetNfcAdapterClient(
std::unique_ptr<NfcAdapterClient> client) {
DBusThreadManager::Get()->client_bundle_->nfc_adapter_client_ =
std::move(client);
}
void DBusThreadManagerSetter::SetNfcDeviceClient(
std::unique_ptr<NfcDeviceClient> client) {
DBusThreadManager::Get()->client_bundle_->nfc_device_client_ =
std::move(client);
}
void DBusThreadManagerSetter::SetNfcManagerClient(
std::unique_ptr<NfcManagerClient> client) {
DBusThreadManager::Get()->client_bundle_->nfc_manager_client_ =
std::move(client);
}
void DBusThreadManagerSetter::SetNfcRecordClient(
std::unique_ptr<NfcRecordClient> client) {
DBusThreadManager::Get()->client_bundle_->nfc_record_client_ =
std::move(client);
}
void DBusThreadManagerSetter::SetNfcTagClient(
std::unique_ptr<NfcTagClient> client) {
DBusThreadManager::Get()->client_bundle_->nfc_tag_client_ = std::move(client);
}
void DBusThreadManagerSetter::SetPermissionBrokerClient(
std::unique_ptr<PermissionBrokerClient> client) {
DBusThreadManager::Get()->client_bundle_->permission_broker_client_ =

@ -38,11 +38,6 @@ class ImageBurnerClient;
class IntrospectableClient;
class LorgnetteManagerClient;
class ModemMessagingClient;
class NfcAdapterClient;
class NfcDeviceClient;
class NfcManagerClient;
class NfcRecordClient;
class NfcTagClient;
class PermissionBrokerClient;
class PowerManagerClient;
class SMSClient;
@ -117,11 +112,6 @@ class CHROMEOS_EXPORT DBusThreadManager {
IntrospectableClient* GetIntrospectableClient();
LorgnetteManagerClient* GetLorgnetteManagerClient();
ModemMessagingClient* GetModemMessagingClient();
NfcAdapterClient* GetNfcAdapterClient();
NfcDeviceClient* GetNfcDeviceClient();
NfcManagerClient* GetNfcManagerClient();
NfcRecordClient* GetNfcRecordClient();
NfcTagClient* GetNfcTagClient();
PermissionBrokerClient* GetPermissionBrokerClient();
PowerManagerClient* GetPowerManagerClient();
SessionManagerClient* GetSessionManagerClient();
@ -195,11 +185,6 @@ class CHROMEOS_EXPORT DBusThreadManagerSetter {
void SetImageBurnerClient(std::unique_ptr<ImageBurnerClient> client);
void SetIntrospectableClient(std::unique_ptr<IntrospectableClient> client);
void SetModemMessagingClient(std::unique_ptr<ModemMessagingClient> client);
void SetNfcAdapterClient(std::unique_ptr<NfcAdapterClient> client);
void SetNfcDeviceClient(std::unique_ptr<NfcDeviceClient> client);
void SetNfcManagerClient(std::unique_ptr<NfcManagerClient> client);
void SetNfcRecordClient(std::unique_ptr<NfcRecordClient> client);
void SetNfcTagClient(std::unique_ptr<NfcTagClient> client);
void SetPermissionBrokerClient(
std::unique_ptr<PermissionBrokerClient> client);
void SetPowerManagerClient(std::unique_ptr<PowerManagerClient> client);

@ -1,327 +0,0 @@
// 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_adapter_client.h"
#include "base/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "dbus/message.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 FakeNfcAdapterClient::kAdapterPath0[] = "/fake/nfc0";
const char FakeNfcAdapterClient::kAdapterPath1[] = "/fake/nfc1";
FakeNfcAdapterClient::Properties::Properties(
const PropertyChangedCallback& callback)
: NfcAdapterClient::Properties(NULL, callback) {
}
FakeNfcAdapterClient::Properties::~Properties() {
}
void FakeNfcAdapterClient::Properties::Get(
dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) {
VLOG(1) << "Get " << property->name();
callback.Run(false);
}
void FakeNfcAdapterClient::Properties::GetAll() {
VLOG(1) << "GetAll";
}
void FakeNfcAdapterClient::Properties::Set(
dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) {
VLOG(1) << "Set " << property->name();
if (property->name() != powered.name()) {
callback.Run(false);
return;
}
// Cannot set the power if currently polling.
if (polling.value()) {
LOG(ERROR) << "Cannot set power while polling.";
callback.Run(false);
return;
}
// Cannot set power if there is a device or a tag that is currently
// "paired".
if (!devices.value().empty() || !tags.value().empty()) {
LOG(ERROR) << "Cannot set power while the device is paired.";
callback.Run(false);
return;
}
// Obtain the cached "set value" and send a property changed signal only if
// its value is different from the current value of the property.
std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
property->AppendSetValueToWriter(&writer);
dbus::MessageReader reader(response.get());
bool set_value = false;
if (!reader.PopVariantOfBool(&set_value) || set_value == powered.value()) {
LOG(WARNING) << "Property has not changed.";
callback.Run(false);
return;
}
property->ReplaceValueWithSetValue();
callback.Run(true);
}
FakeNfcAdapterClient::FakeNfcAdapterClient()
: present_(true),
second_present_(false),
start_pairing_on_poll_(true),
device_pairing_(false) {
VLOG(1) << "Creating FakeNfcAdapterClient";
std::vector<std::string> protocols;
protocols.push_back(nfc_common::kProtocolFelica);
protocols.push_back(nfc_common::kProtocolMifare);
protocols.push_back(nfc_common::kProtocolJewel);
protocols.push_back(nfc_common::kProtocolIsoDep);
protocols.push_back(nfc_common::kProtocolNfcDep);
properties_.reset(new Properties(base::Bind(
&FakeNfcAdapterClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kAdapterPath0))));
properties_->protocols.ReplaceValue(protocols);
second_properties_.reset(new Properties(base::Bind(
&FakeNfcAdapterClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kAdapterPath1))));
second_properties_->protocols.ReplaceValue(protocols);
}
FakeNfcAdapterClient::~FakeNfcAdapterClient() {
}
void FakeNfcAdapterClient::Init(dbus::Bus* bus) {
}
void FakeNfcAdapterClient::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void FakeNfcAdapterClient::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
std::vector<dbus::ObjectPath> FakeNfcAdapterClient::GetAdapters() {
std::vector<dbus::ObjectPath> object_paths;
if (present_)
object_paths.push_back(dbus::ObjectPath(kAdapterPath0));
if (second_present_)
object_paths.push_back(dbus::ObjectPath(kAdapterPath1));
return object_paths;
}
FakeNfcAdapterClient::Properties*
FakeNfcAdapterClient::GetProperties(const dbus::ObjectPath& object_path) {
if (object_path == dbus::ObjectPath(kAdapterPath0))
return properties_.get();
if (object_path == dbus::ObjectPath(kAdapterPath1))
return second_properties_.get();
return NULL;
}
void FakeNfcAdapterClient::StartPollLoop(
const dbus::ObjectPath& object_path,
const std::string& mode,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) {
VLOG(1) << "FakeNfcAdapterClient::StartPollLoop";
if (object_path != dbus::ObjectPath(kAdapterPath0)) {
error_callback.Run(nfc_client_helpers::kNoResponseError, "");
return;
}
if (!properties_->powered.value()) {
error_callback.Run(nfc_error::kFailed, "Adapter not powered.");
return;
}
if (properties_->polling.value()) {
error_callback.Run(nfc_error::kFailed, "Already polling.");
return;
}
if (!properties_->devices.value().empty() ||
!properties_->tags.value().empty()) {
error_callback.Run(nfc_error::kFailed, "Adapter busy.");
return;
}
properties_->polling.ReplaceValue(true);
properties_->mode.ReplaceValue(mode);
callback.Run();
if (!start_pairing_on_poll_)
return;
if (device_pairing_) {
FakeNfcDeviceClient* device_client =
static_cast<FakeNfcDeviceClient*>(
DBusThreadManager::Get()->GetNfcDeviceClient());
device_client->BeginPairingSimulation(3000, 2000);
} else {
FakeNfcTagClient* tag_client =
static_cast<FakeNfcTagClient*>(
DBusThreadManager::Get()->GetNfcTagClient());
tag_client->BeginPairingSimulation(2000);
}
device_pairing_ = !device_pairing_;
}
void FakeNfcAdapterClient::StopPollLoop(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) {
VLOG(1) << "FakeNfcAdapterClient::StopPollLoop.";
if (object_path != dbus::ObjectPath(kAdapterPath0)) {
error_callback.Run(nfc_client_helpers::kNoResponseError, "");
return;
}
if (!properties_->polling.value()) {
error_callback.Run("org.neard.Error.Failed", "Not polling.");
return;
}
FakeNfcDeviceClient* device_client =
static_cast<FakeNfcDeviceClient*>(
DBusThreadManager::Get()->GetNfcDeviceClient());
device_client->EndPairingSimulation();
FakeNfcTagClient* tag_client =
static_cast<FakeNfcTagClient*>(
DBusThreadManager::Get()->GetNfcTagClient());
tag_client->EndPairingSimulation();
properties_->polling.ReplaceValue(false);
callback.Run();
}
void FakeNfcAdapterClient::SetAdapterPresent(bool present) {
if (present == present_)
return;
present_ = present;
if (present_) {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterAdded(dbus::ObjectPath(kAdapterPath0)));
} else {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterRemoved(dbus::ObjectPath(kAdapterPath0)));
}
}
void FakeNfcAdapterClient::SetSecondAdapterPresent(bool present) {
if (present == second_present_)
return;
second_present_ = present;
if (present_) {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterAdded(dbus::ObjectPath(kAdapterPath1)));
} else {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterRemoved(dbus::ObjectPath(kAdapterPath1)));
}
}
void FakeNfcAdapterClient::SetDevice(const dbus::ObjectPath& device_path) {
LOG(INFO) << "Add device path to the fake adapter: " << device_path.value();
if (!properties_->polling.value()) {
LOG(ERROR) << "Adapter not polling, cannot set device.";
return;
}
const ObjectPathVector& devices(properties_->devices.value());
for (ObjectPathVector::const_iterator iter = devices.begin();
iter != devices.end(); ++iter) {
if (*iter == device_path) {
LOG(WARNING) << "Device path already in list of devices.";
return;
}
}
// Mark as not polling.
properties_->polling.ReplaceValue(false);
ObjectPathVector new_devices = devices;
new_devices.push_back(device_path);
properties_->devices.ReplaceValue(new_devices);
}
void FakeNfcAdapterClient::SetTag(const dbus::ObjectPath& tag_path) {
LOG(INFO) << "Add tag path to the fake adapter: " << tag_path.value();
if (!properties_->polling.value()) {
LOG(ERROR) << "Adapter not polling, cannot set tag.";
return;
}
const ObjectPathVector& tags(properties_->tags.value());
for (ObjectPathVector::const_iterator iter = tags.begin();
iter != tags.end(); ++iter) {
if (*iter == tag_path) {
LOG(WARNING) << "Tag path already in list of tags.";
return;
}
}
// Mark as not polling.
properties_->polling.ReplaceValue(false);
ObjectPathVector new_tags = tags;
new_tags.push_back(tag_path);
properties_->tags.ReplaceValue(new_tags);
}
void FakeNfcAdapterClient::UnsetDevice(const dbus::ObjectPath& device_path) {
LOG(INFO) << "Remove device path from the fake adapter: "
<< device_path.value();
ObjectPathVector new_devices = properties_->devices.value();
for (ObjectPathVector::iterator iter = new_devices.begin();
iter != new_devices.end(); ++iter) {
if (*iter == device_path) {
new_devices.erase(iter);
properties_->devices.ReplaceValue(new_devices);
// Mark as polling.
DCHECK(!properties_->polling.value());
properties_->polling.ReplaceValue(true);
return;
}
}
LOG(WARNING) << "Device path not in list of devices.";
}
void FakeNfcAdapterClient::UnsetTag(const dbus::ObjectPath& tag_path) {
LOG(INFO) << "Remove tag path from the fake adapter: " << tag_path.value();
ObjectPathVector new_tags = properties_->tags.value();
for (ObjectPathVector::iterator iter = new_tags.begin();
iter != new_tags.end(); ++iter) {
if (*iter == tag_path) {
new_tags.erase(iter);
properties_->tags.ReplaceValue(new_tags);
// Mark as polling.
DCHECK(!properties_->polling.value());
properties_->polling.ReplaceValue(true);
return;
}
}
LOG(WARNING) << "Tag path not in list of tags.";
}
void FakeNfcAdapterClient::EnablePairingOnPoll(bool enabled) {
start_pairing_on_poll_ = enabled;
}
void FakeNfcAdapterClient::OnPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterPropertyChanged(object_path, property_name));
}
} // namespace chromeos

@ -1,117 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_FAKE_NFC_ADAPTER_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_NFC_ADAPTER_CLIENT_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
namespace chromeos {
// FakeNfcAdapterClient simulates the behavior of the NFC adapter objects
// and is used both in test cases in place of a mock and on the Linux desktop.
class CHROMEOS_EXPORT FakeNfcAdapterClient : public NfcAdapterClient {
public:
// The object paths for the adapters that are being emulated.
static const char kAdapterPath0[];
static const char kAdapterPath1[];
// Properties structure that provides fake behavior for D-Bus calls.
struct Properties : public NfcAdapterClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet overrides.
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeNfcAdapterClient();
~FakeNfcAdapterClient() override;
// NfcAdapterClient overrides.
void Init(dbus::Bus* bus) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetAdapters() override;
Properties* GetProperties(const dbus::ObjectPath& object_path) override;
void StartPollLoop(
const dbus::ObjectPath& object_path,
const std::string& mode,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override;
void StopPollLoop(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override;
// Sets the adapter as |present|. Used for testing.
void SetAdapterPresent(bool present);
void SetSecondAdapterPresent(bool present);
// Tells the FakeNfcAdapterClient to add the device or tag with the given path
// to its corresponding list for |kAdapterPath0|, if it is not already in
// the list and promptly triggers a property changed signal. This method will
// also fail, if the polling property of the adapter is false and will set it
// to false on success.
void SetDevice(const dbus::ObjectPath& device_path);
void SetTag(const dbus::ObjectPath& tag_path);
// Tells the FakeNfcAdapterClient to remove the device or tag with the given
// path from its corresponding list exposed for |kAdapterPath0|, if it
// is in the list. On success, this method will mark the polling property of
// the adapter to true.
void UnsetDevice(const dbus::ObjectPath& device_path);
void UnsetTag(const dbus::ObjectPath& tag_path);
// Sets a flag that determines whether FakeNfcAdapterClient should notify
// FakeNfcDeviceClient or FakeNfcTagClient to start a pairing simulation as a
// result of a call to StartPollLoop(). This is enabled by default. If
// enabled, the first call to StartPollLoop, will initiate a tag pairing
// simulation. The simulation will alternate between device and tag pairing on
// each successive call to StartPollLoop. This behavior, which is meant for
// feature development based on fake classes, can be disabled to allow manual
// control for unit tests.
void EnablePairingOnPoll(bool enabled);
private:
// Property changed callback passed when we create Properties* structures.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// List of observers interested in event notifications from us.
base::ObserverList<Observer> observers_;
// Fake properties that are returned for the emulated adapters.
std::unique_ptr<Properties> properties_;
std::unique_ptr<Properties> second_properties_;
// Whether the adapter and second adapter are present or not.
bool present_;
bool second_present_;
// If true, a pairing simulation is initiated on a successful call to
// StartPollLoop().
bool start_pairing_on_poll_;
// If true, device pairing will be simulated on the next call to
// StartPollLoop. Otherwise, tag pairing will be simulated.
bool device_pairing_;
DISALLOW_COPY_AND_ASSIGN(FakeNfcAdapterClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_NFC_ADAPTER_CLIENT_H_

@ -1,240 +0,0 @@
// 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/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/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 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::ThreadTaskRunnerHandle::Get()->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::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::Bind(&FakeNfcDeviceClient::HandleSimulationTimeout,
base::Unretained(this)),
base::TimeDelta::FromMilliseconds(simulation_timeout_));
}
return;
}
base::ThreadTaskRunnerHandle::Get()->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::ThreadTaskRunnerHandle::Get()->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

@ -1,133 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_
#include <memory>
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_device_client.h"
namespace chromeos {
// FakeNfcDeviceClient simulates the behavior of the NFC device objects
// and is used both in test cases in place of a mock and on the Linux desktop.
class CHROMEOS_EXPORT FakeNfcDeviceClient : public NfcDeviceClient {
public:
// The fake device object path.
static const char kDevicePath[];
// The default simulation timeout interval.
static const int kDefaultSimulationTimeoutMilliseconds;
// Properties structure that provides fake behavior for D-Bus calls.
struct Properties : public NfcDeviceClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet overrides.
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeNfcDeviceClient();
~FakeNfcDeviceClient() override;
// NfcDeviceClient overrides.
void Init(dbus::Bus* bus) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetDevicesForAdapter(
const dbus::ObjectPath& adapter_path) override;
Properties* GetProperties(const dbus::ObjectPath& object_path) override;
void Push(const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override;
// Simulates the appearance of a device. The fake device will show up after
// exactly |visibility_delay| milliseconds, and will simulate pushing a single
// record to the local fake adapter after exactly |record_push_delay|
// milliseconds after the the device appears. |visibility_delay| must have a
// non-negative value. |record_push_delay| CAN be negative: if it has a
// negative value, the record push step will not be simulated. The
// side-effects of this method occur asynchronously, i.e. even with arguments
// with value 0, the pairing won't take place until after this method has
// returned.
void BeginPairingSimulation(int visibility_delay, int record_push_delay);
// If device pairing was previously started, simulates the disappearance of
// the device. Any device objects presented and their records will disappear
// after this call. Delayed events that were set up by a previous call to
// BeginPairing() will be canceled through a call to EndPairing().
void EndPairingSimulation();
// Enables or disables automatic unpairing. When enabled, a pairing
// simulation will end |simulation_timeout| milliseconds after records have
// been exposed (or after the tag has been exposed, if |record_push_delay| was
// given as a negative value to BeginPairingSimulation) This is enabled by
// default and the timeout is set to |kDefaultSimulationTimeoutMilliseconds|.
void EnableSimulationTimeout(int simulation_timeout);
void DisableSimulationTimeout();
// Tells the FakeNfcDeviceClient to add the records in |record_paths| to its
// list of records exposed for |kDevicePath|. This method will immediately
// assign the records and trigger a property changed signal, only if the
// device is currently visible.
void SetRecords(const std::vector<dbus::ObjectPath>& record_paths);
// Tells the FakeNfcDeviceClient to clear the list of records exposed for
// |kDevicePath|. This method takes effect immediately and triggers a
// property changed signal.
void ClearRecords();
// Returns true, if a pairing simulation is currently going on.
bool device_visible() const { return device_visible_; }
private:
// Property changed callback passed when we create Properties* structures.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// Makes the fake device visible (if it is not already so) and simulates a
// record push after |record_push_delay| seconds. Posted by BeginPairing().
void MakeDeviceVisible(int record_push_delay);
// Makes the fake records visible. Called by MakeDeviceVisible().
void MakeRecordsVisible();
// Called when the simulation timeout expires.
void HandleSimulationTimeout();
// List of observers interested in event notifications from us.
base::ObserverList<Observer> observers_;
// Fake properties that are returned for the emulated device.
std::unique_ptr<Properties> properties_;
// If true, a pairing simulation was started using BeginPairing() and no call
// to EndPairing() has been made.
bool pairing_started_;
// If true, observers have been notified that a device has been created and
// the device properties are accessible.
bool device_visible_;
// If non-negative, the device will disappear this many milliseconds after
// its records have been exposed.
int simulation_timeout_;
DISALLOW_COPY_AND_ASSIGN(FakeNfcDeviceClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_NFC_DEVICE_CLIENT_H_

@ -1,100 +0,0 @@
// Copyright (c) 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_manager_client.h"
#include "base/bind.h"
#include "base/logging.h"
#include "dbus/object_path.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
const char FakeNfcManagerClient::kDefaultAdapterPath[] = "/fake/nfc0";
FakeNfcManagerClient::Properties::Properties(
const PropertyChangedCallback& callback)
: NfcManagerClient::Properties(NULL, callback) {
}
FakeNfcManagerClient::Properties::~Properties() {
}
void FakeNfcManagerClient::Properties::Get(
dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) {
VLOG(1) << "Get " << property->name();
callback.Run(false);
}
void FakeNfcManagerClient::Properties::GetAll() {
VLOG(1) << "GetAll";
}
void FakeNfcManagerClient::Properties::Set(
dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) {
VLOG(1) << "Set " << property->name();
callback.Run(false);
}
FakeNfcManagerClient::FakeNfcManagerClient() {
properties_.reset(new Properties(base::Bind(
&FakeNfcManagerClient::OnPropertyChanged, base::Unretained(this))));
AddAdapter(kDefaultAdapterPath);
}
FakeNfcManagerClient::~FakeNfcManagerClient() {
}
void FakeNfcManagerClient::Init(dbus::Bus* bus) {
}
void FakeNfcManagerClient::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void FakeNfcManagerClient::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
FakeNfcManagerClient::Properties* FakeNfcManagerClient::GetProperties() {
return properties_.get();
}
void FakeNfcManagerClient::AddAdapter(const std::string& adapter_path) {
VLOG(1) << "Adding NFC adapter: " << adapter_path;
dbus::ObjectPath new_adapter(adapter_path);
std::pair<std::set<dbus::ObjectPath>::iterator, bool> result =
adapters_.insert(new_adapter);
if (!result.second) {
VLOG(1) << "Adapter \"" << adapter_path << "\" already exists.";
return;
}
// Create a vector containing all object paths in the set |adapters_|. This
// will copy all members of |adapters_| to |adapters|.
std::vector<dbus::ObjectPath> adapters(adapters_.begin(), adapters_.end());
properties_->adapters.ReplaceValue(adapters);
FOR_EACH_OBSERVER(Observer, observers_, AdapterAdded(new_adapter));
}
void FakeNfcManagerClient::RemoveAdapter(const std::string& adapter_path) {
VLOG(1) << "Removing NFC adapter: " << adapter_path;
dbus::ObjectPath to_remove(adapter_path);
if (adapters_.erase(to_remove) == 0) {
VLOG(1) << "No such adapter: \"" << adapter_path << "\"";
return;
}
std::vector<dbus::ObjectPath> adapters(adapters_.begin(), adapters_.end());
properties_->adapters.ReplaceValue(adapters);
FOR_EACH_OBSERVER(Observer, observers_, AdapterRemoved(to_remove));
}
void FakeNfcManagerClient::OnPropertyChanged(
const std::string& property_name) {
FOR_EACH_OBSERVER(Observer, observers_,
ManagerPropertyChanged(property_name));
}
} // namespace chromeos

@ -1,70 +0,0 @@
// Copyright (c) 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.
#ifndef CHROMEOS_DBUS_FAKE_NFC_MANAGER_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_NFC_MANAGER_CLIENT_H_
#include <set>
#include <string>
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_manager_client.h"
#include "dbus/property.h"
namespace chromeos {
// FakeNfcManagerClient simulates the behavior of the NFC Daemon manager object
// and is used both in test cases in place of a mock and on the Linux desktop.
class CHROMEOS_EXPORT FakeNfcManagerClient : public NfcManagerClient {
public:
struct Properties : public NfcManagerClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet overrides.
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeNfcManagerClient();
~FakeNfcManagerClient() override;
// NfcManagerClient overrides.
void Init(dbus::Bus* bus) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
Properties* GetProperties() override;
// Methods to simulate adapters getting added and removed.
void AddAdapter(const std::string& adapter_path);
void RemoveAdapter(const std::string& adapter_path);
// Default path of an adapter that is simulated for testing.
static const char kDefaultAdapterPath[];
private:
// Property callback passed when we create Properties* structures.
void OnPropertyChanged(const std::string& property_name);
// List of observers interested in event notifications.
base::ObserverList<Observer> observers_;
// Set containing the currently simulated adapters.
std::set<dbus::ObjectPath> adapters_;
// Fake properties object. This gets updated whenever AddAdapter or
// RemoveAdapter gets called.
std::unique_ptr<Properties> properties_;
DISALLOW_COPY_AND_ASSIGN(FakeNfcManagerClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_NFC_MANAGER_CLIENT_H_

@ -1,322 +0,0 @@
// 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_record_client.h"
#include <stdint.h>
#include "base/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
namespace {
// Gets and returns the value for |key| in |dictionary| as a string. If |key| is
// not found, returns an empty string.
std::string GetStringValue(const base::DictionaryValue& dictionary,
const std::string& key) {
std::string value;
bool result = dictionary.GetString(key, &value);
// Simply return |value|. |value| will remain untouched if
// base::DictionaryValue::GetString returns false.
DCHECK(result || value.empty());
return value;
}
// Gets and returns the value for |key| in |dictionary| as a double. If |key| is
// not found, returns 0.
double GetDoubleValue(const base::DictionaryValue& dictionary,
const std::string& key) {
double value = 0;
bool result = dictionary.GetDouble(key, &value);
// Simply return |value|. |value| will remain untouched if
// base::DictionaryValue::GetString returns false.
DCHECK(result || !value);
return value;
}
} // namespace
const char FakeNfcRecordClient::kDeviceSmartPosterRecordPath[] =
"/fake/device/record0";
const char FakeNfcRecordClient::kDeviceTextRecordPath[] =
"/fake/device/record1";
const char FakeNfcRecordClient::kDeviceUriRecordPath[] = "/fake/device/record2";
const char FakeNfcRecordClient::kTagRecordPath[] = "/fake/tag/record0";
FakeNfcRecordClient::Properties::Properties(
const PropertyChangedCallback& callback)
: NfcRecordClient::Properties(NULL, callback) {
}
FakeNfcRecordClient::Properties::~Properties() {
}
void FakeNfcRecordClient::Properties::Get(
dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) {
VLOG(1) << "Get " << property->name();
callback.Run(false);
}
void FakeNfcRecordClient::Properties::GetAll() {
VLOG(1) << "GetAll";
if (!on_get_all_callback().is_null())
on_get_all_callback().Run();
}
void FakeNfcRecordClient::Properties::Set(
dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) {
VLOG(1) << "Set " << property->name();
callback.Run(false);
}
FakeNfcRecordClient::FakeNfcRecordClient()
: device_records_visible_(false),
tag_records_visible_(false) {
VLOG(1) << "Creating FakeNfcRecordClient";
device_smart_poster_record_properties_.reset(new Properties(
base::Bind(&FakeNfcRecordClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kDeviceSmartPosterRecordPath))));
device_smart_poster_record_properties_->SetAllPropertiesReceivedCallback(
base::Bind(&FakeNfcRecordClient::OnPropertiesReceived,
base::Unretained(this),
dbus::ObjectPath(kDeviceSmartPosterRecordPath)));
device_text_record_properties_.reset(new Properties(
base::Bind(&FakeNfcRecordClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kDeviceTextRecordPath))));
device_text_record_properties_->SetAllPropertiesReceivedCallback(
base::Bind(&FakeNfcRecordClient::OnPropertiesReceived,
base::Unretained(this),
dbus::ObjectPath(kDeviceTextRecordPath)));
device_uri_record_properties_.reset(new Properties(
base::Bind(&FakeNfcRecordClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kDeviceUriRecordPath))));
device_uri_record_properties_->SetAllPropertiesReceivedCallback(
base::Bind(&FakeNfcRecordClient::OnPropertiesReceived,
base::Unretained(this),
dbus::ObjectPath(kDeviceUriRecordPath)));
tag_record_properties_.reset(new Properties(
base::Bind(&FakeNfcRecordClient::OnPropertyChanged,
base::Unretained(this),
dbus::ObjectPath(kTagRecordPath))));
}
FakeNfcRecordClient::~FakeNfcRecordClient() {
}
void FakeNfcRecordClient::Init(dbus::Bus* bus) {
}
void FakeNfcRecordClient::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
void FakeNfcRecordClient::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
std::vector<dbus::ObjectPath> FakeNfcRecordClient::GetRecordsForDevice(
const dbus::ObjectPath& device_path) {
std::vector<dbus::ObjectPath> record_paths;
if (device_records_visible_ &&
device_path == dbus::ObjectPath(FakeNfcDeviceClient::kDevicePath)) {
record_paths.push_back(dbus::ObjectPath(kDeviceSmartPosterRecordPath));
record_paths.push_back(dbus::ObjectPath(kDeviceTextRecordPath));
record_paths.push_back(dbus::ObjectPath(kDeviceUriRecordPath));
}
return record_paths;
}
std::vector<dbus::ObjectPath> FakeNfcRecordClient::GetRecordsForTag(
const dbus::ObjectPath& tag_path) {
std::vector<dbus::ObjectPath> record_paths;
if (tag_records_visible_ && tag_path.value() == FakeNfcTagClient::kTagPath)
record_paths.push_back(dbus::ObjectPath(kTagRecordPath));
return record_paths;
}
FakeNfcRecordClient::Properties*
FakeNfcRecordClient::GetProperties(const dbus::ObjectPath& object_path) {
if (device_records_visible_) {
if (object_path.value() == kDeviceSmartPosterRecordPath)
return device_smart_poster_record_properties_.get();
if (object_path.value() == kDeviceTextRecordPath)
return device_text_record_properties_.get();
if (object_path.value() == kDeviceUriRecordPath)
return device_uri_record_properties_.get();
return NULL;
}
if (tag_records_visible_ && object_path.value() == kTagRecordPath)
return tag_record_properties_.get();
return NULL;
}
void FakeNfcRecordClient::SetDeviceRecordsVisible(bool visible) {
if (device_records_visible_ == visible) {
VLOG(1) << "Record visibility is already: " << visible;
return;
}
FakeNfcDeviceClient* device_client = static_cast<FakeNfcDeviceClient*>(
DBusThreadManager::Get()->GetNfcDeviceClient());
if (!device_client->device_visible()) {
VLOG(1) << "Cannot set records when device is not visible.";
return;
}
if (!visible) {
device_client->ClearRecords();
FOR_EACH_OBSERVER(
NfcRecordClient::Observer, observers_,
RecordRemoved(dbus::ObjectPath(kDeviceSmartPosterRecordPath)));
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordRemoved(dbus::ObjectPath(kDeviceTextRecordPath)));
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordRemoved(dbus::ObjectPath(kDeviceUriRecordPath)));
device_records_visible_ = visible;
return;
}
device_records_visible_ = visible;
std::vector<dbus::ObjectPath> record_paths =
GetRecordsForDevice(
dbus::ObjectPath(FakeNfcDeviceClient::kDevicePath));
device_client->SetRecords(record_paths);
// Reassign each property and send signals.
FOR_EACH_OBSERVER(
NfcRecordClient::Observer, observers_,
RecordAdded(dbus::ObjectPath(kDeviceSmartPosterRecordPath)));
device_smart_poster_record_properties_->type.ReplaceValue(
nfc_record::kTypeSmartPoster);
device_smart_poster_record_properties_->uri.ReplaceValue(
"http://fake.uri0.fake");
device_smart_poster_record_properties_->mime_type.ReplaceValue("text/fake");
device_smart_poster_record_properties_->size.ReplaceValue(128);
device_smart_poster_record_properties_->
representation.ReplaceValue("Fake Title");
device_smart_poster_record_properties_->encoding.ReplaceValue(
nfc_record::kEncodingUtf16);
device_smart_poster_record_properties_->language.ReplaceValue("en");
OnPropertiesReceived(dbus::ObjectPath(kDeviceSmartPosterRecordPath));
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordAdded(dbus::ObjectPath(kDeviceTextRecordPath)));
device_text_record_properties_->type.ReplaceValue(nfc_record::kTypeText);
device_text_record_properties_->representation.ReplaceValue(
"Kablosuz \xC4\xb0leti\xC5\x9fim");
device_text_record_properties_->encoding.ReplaceValue(
nfc_record::kEncodingUtf8);
device_text_record_properties_->language.ReplaceValue("tr");
OnPropertiesReceived(dbus::ObjectPath(kDeviceTextRecordPath));
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordAdded(dbus::ObjectPath(kDeviceUriRecordPath)));
device_uri_record_properties_->type.ReplaceValue(nfc_record::kTypeUri);
device_uri_record_properties_->uri.ReplaceValue("file://some/fake/path");
device_uri_record_properties_->mime_type.ReplaceValue("text/fake");
device_uri_record_properties_->size.ReplaceValue(512);
OnPropertiesReceived(dbus::ObjectPath(kDeviceUriRecordPath));
}
void FakeNfcRecordClient::SetTagRecordsVisible(bool visible) {
if (tag_records_visible_ == visible) {
VLOG(1) << "Record visibility is already: " << visible;
return;
}
FakeNfcTagClient* tag_client = static_cast<FakeNfcTagClient*>(
DBusThreadManager::Get()->GetNfcTagClient());
if (!tag_client->tag_visible()) {
VLOG(1) << "Cannot set records when tag is not visible.";
return;
}
if (!visible) {
tag_client->ClearRecords();
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordRemoved(dbus::ObjectPath(kTagRecordPath)));
tag_records_visible_ = visible;
return;
}
tag_records_visible_ = visible;
std::vector<dbus::ObjectPath> record_paths =
GetRecordsForTag(dbus::ObjectPath(FakeNfcTagClient::kTagPath));
tag_client->SetRecords(record_paths);
// Reassign each property to its current value to trigger a property change
// signal.
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordAdded(dbus::ObjectPath(kTagRecordPath)));
tag_record_properties_->type.ReplaceValue(
tag_record_properties_->type.value());
tag_record_properties_->representation.ReplaceValue(
tag_record_properties_->representation.value());
tag_record_properties_->encoding.ReplaceValue(
tag_record_properties_->encoding.value());
tag_record_properties_->language.ReplaceValue(
tag_record_properties_->language.value());
tag_record_properties_->uri.ReplaceValue(
tag_record_properties_->uri.value());
tag_record_properties_->mime_type.ReplaceValue(
tag_record_properties_->mime_type.value());
tag_record_properties_->size.ReplaceValue(
tag_record_properties_->size.value());
tag_record_properties_->action.ReplaceValue(
tag_record_properties_->action.value());
OnPropertiesReceived(dbus::ObjectPath(kTagRecordPath));
}
bool FakeNfcRecordClient::WriteTagRecord(
const base::DictionaryValue& attributes) {
if (attributes.empty())
return false;
tag_record_properties_->type.ReplaceValue(
GetStringValue(attributes, nfc_record::kTypeProperty));
tag_record_properties_->encoding.ReplaceValue(
GetStringValue(attributes, nfc_record::kEncodingProperty));
tag_record_properties_->language.ReplaceValue(
GetStringValue(attributes, nfc_record::kLanguageProperty));
tag_record_properties_->representation.ReplaceValue(
GetStringValue(attributes, nfc_record::kRepresentationProperty));
tag_record_properties_->uri.ReplaceValue(
GetStringValue(attributes, nfc_record::kUriProperty));
tag_record_properties_->mime_type.ReplaceValue(
GetStringValue(attributes, nfc_record::kMimeTypeProperty));
tag_record_properties_->action.ReplaceValue(
GetStringValue(attributes, nfc_record::kActionProperty));
tag_record_properties_->size.ReplaceValue(static_cast<uint32_t>(
GetDoubleValue(attributes, nfc_record::kSizeProperty)));
SetTagRecordsVisible(false);
SetTagRecordsVisible(true);
return true;
}
void FakeNfcRecordClient::OnPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordPropertyChanged(object_path, property_name));
}
void FakeNfcRecordClient::OnPropertiesReceived(
const dbus::ObjectPath& object_path) {
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordPropertiesReceived(object_path));
}
} // namespace chromeos

@ -1,93 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_FAKE_NFC_RECORD_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_NFC_RECORD_CLIENT_H_
#include <memory>
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/values.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "dbus/object_path.h"
namespace chromeos {
// FakeNfcRecordClient simulates the behavior of the NFC record objects and is
// used both in test cases in place of a mock and on the Linux desktop.
class CHROMEOS_EXPORT FakeNfcRecordClient : public NfcRecordClient {
public:
// Paths of the records exposed.
static const char kDeviceSmartPosterRecordPath[];
static const char kDeviceTextRecordPath[];
static const char kDeviceUriRecordPath[];
static const char kTagRecordPath[];
// Properties structure that provides fake behavior for D-Bus calls.
struct Properties : public NfcRecordClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet overrides.
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeNfcRecordClient();
~FakeNfcRecordClient() override;
// NfcTagClient overrides.
void Init(dbus::Bus* bus) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetRecordsForDevice(
const dbus::ObjectPath& device_path) override;
std::vector<dbus::ObjectPath> GetRecordsForTag(
const dbus::ObjectPath& tag_path) override;
Properties* GetProperties(const dbus::ObjectPath& object_path) override;
// Adds or removes the fake record objects and notifies the observers.
void SetDeviceRecordsVisible(bool visible);
void SetTagRecordsVisible(bool visible);
// Modifies the contents of the tag record. |attributes| should be the
// same as the argument to NfcTagClient::Write. Each field will be directly
// assigned to the underlying record based on the type property, with
// no validity checking. Invalid tag content can be passed here to test
// the case where the remote application returns an incorrectly formatted
// record.
bool WriteTagRecord(const base::DictionaryValue& attributes);
private:
// Property changed callback passed when we create Properties* structures.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// Called by Properties* structures when GetAll is called.
void OnPropertiesReceived(const dbus::ObjectPath& object_path);
// If true, the records are currently visible.
bool device_records_visible_;
bool tag_records_visible_;
// List of observers interested in event notifications from us.
base::ObserverList<Observer> observers_;
// Fake properties that are returned for the fake records.
std::unique_ptr<Properties> device_smart_poster_record_properties_;
std::unique_ptr<Properties> device_text_record_properties_;
std::unique_ptr<Properties> device_uri_record_properties_;
std::unique_ptr<Properties> tag_record_properties_;
DISALLOW_COPY_AND_ASSIGN(FakeNfcRecordClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_NFC_RECORD_CLIENT_H_

@ -1,227 +0,0 @@
// 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/threading/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<dbus::ObjectPath> FakeNfcTagClient::GetTagsForAdapter(
const dbus::ObjectPath& adapter_path) {
std::vector<dbus::ObjectPath> 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<FakeNfcRecordClient*>(
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<FakeNfcRecordClient*>(
DBusThreadManager::Get()->GetNfcRecordClient());
record_client->SetTagRecordsVisible(false);
}
// Remove the tag.
FOR_EACH_OBSERVER(Observer, observers_,
TagRemoved(dbus::ObjectPath(kTagPath)));
FakeNfcAdapterClient* adapter_client =
static_cast<FakeNfcAdapterClient*>(
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<dbus::ObjectPath>& 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<FakeNfcAdapterClient*>(
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

@ -1,122 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_
#define CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_tag_client.h"
namespace chromeos {
// FakeNfcTagClient simulates the behavior of the NFC tag objects
// and is used both in test cases in place of a mock and on the Linux desktop.
class CHROMEOS_EXPORT FakeNfcTagClient : public NfcTagClient {
public:
// The fake tag object path.
static const char kTagPath[];
// The default simulation timeout interval.
static const int kDefaultSimulationTimeoutMilliseconds;
struct Properties : public NfcTagClient::Properties {
explicit Properties(const PropertyChangedCallback& callback);
~Properties() override;
// dbus::PropertySet overrides.
void Get(dbus::PropertyBase* property,
dbus::PropertySet::GetCallback callback) override;
void GetAll() override;
void Set(dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) override;
};
FakeNfcTagClient();
~FakeNfcTagClient() override;
// NfcTagClient overrides.
void Init(dbus::Bus* bus) override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetTagsForAdapter(
const dbus::ObjectPath& adapter_path) override;
Properties* GetProperties(const dbus::ObjectPath& object_path) override;
void Write(const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override;
// Simulates the appearance of a tag. The fake tag will show up after
// exactly |visibility_delay| milliseconds. |visibility_delay| must have a
// non-negative value. The side-effects of this method
// occur asynchronously, i.e. even with an argument of 0, the pairing will not
// take place until after this method has returned.
void BeginPairingSimulation(int visibility_delay);
// If tag pairing was previously started, simulates the disappearance of
// the tag. Any tag object presented and their records will disappear
// after this call. Delayed events that were set up by a previous call to
// BeginPairing() will be canceled through a call to EndPairing().
void EndPairingSimulation();
// Enables or disables automatic unpairing. When enabled, a pairing
// simulation will end |simulation_timeout| milliseconds after the tag has
// been exposed. This is enabled by default and the timeout is set to
// |kDefaultSimulationTimeoutMilliseconds|. |simulation_timeout| must be
// non-negative.
void EnableSimulationTimeout(int simulation_timeout);
void DisableSimulationTimeout();
// Tells the FakeNfcDeviceClient to add the records in |record_paths| to its
// list of records exposed for |kDevicePath|. This method will immediately
// assign the records and trigger a property changed signal, only if the
// tag is currently visible.
void SetRecords(const std::vector<dbus::ObjectPath>& record_paths);
// Tells the FakeNfcDeviceClient to clear the list of records exposed for
// |kDevicePath|. This method takes effect immediately and triggers a
// property changed signal.
void ClearRecords();
// Returns true, if a pairing simulation is currently going on.
bool tag_visible() const { return tag_visible_; }
private:
// Property changed callback passed when we create Properties* structures.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// Makes the fake tag visible if it is not already visible.
void MakeTagVisible();
// Called when the simulation timeout expires.
void HandleSimulationTimeout();
// List of observers interested in event notifications from us.
base::ObserverList<Observer> observers_;
// Fake properties that are returned for the emulated tag.
std::unique_ptr<Properties> properties_;
// If true, a pairing simulation was begun using BeginPairing() and no call
// to EndPairing() has been made.
bool pairing_started_;
// If true, observers have been notified that a tag has been created and
// the tag properties are accesible.
bool tag_visible_;
// If non-negative, the tag will disappear this many milliseconds after
// its records have been exposed.
int simulation_timeout_;
DISALLOW_COPY_AND_ASSIGN(FakeNfcTagClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_FAKE_NFC_TAG_CLIENT_H_

@ -1,223 +0,0 @@
// 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/nfc_adapter_client.h"
#include <map>
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/nfc_manager_client.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
NfcAdapterClient::Properties::Properties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: NfcPropertySet(object_proxy,
nfc_adapter::kNfcAdapterInterface,
callback) {
RegisterProperty(nfc_adapter::kModeProperty, &mode);
RegisterProperty(nfc_adapter::kPoweredProperty, &powered);
RegisterProperty(nfc_adapter::kPollingProperty, &polling);
RegisterProperty(nfc_adapter::kProtocolsProperty, &protocols);
RegisterProperty(nfc_adapter::kTagsProperty, &tags);
RegisterProperty(nfc_adapter::kDevicesProperty, &devices);
}
NfcAdapterClient::Properties::~Properties() {
}
// The NfcAdapterClient implementation used in production.
class NfcAdapterClientImpl
: public NfcAdapterClient,
public NfcManagerClient::Observer,
public nfc_client_helpers::DBusObjectMap::Delegate {
public:
explicit NfcAdapterClientImpl(NfcManagerClient* manager_client)
: bus_(NULL),
manager_client_(manager_client),
weak_ptr_factory_(this) {
DCHECK(manager_client);
}
~NfcAdapterClientImpl() override { manager_client_->RemoveObserver(this); }
// NfcAdapterClient override.
void AddObserver(NfcAdapterClient::Observer* observer) override {
DCHECK(observer);
observers_.AddObserver(observer);
}
// NfcAdapterClient override.
void RemoveObserver(NfcAdapterClient::Observer* observer) override {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
// NfcAdapterClient override.
std::vector<dbus::ObjectPath> GetAdapters() override {
return object_map_->GetObjectPaths();
}
// NfcAdapterClient override.
Properties* GetProperties(const dbus::ObjectPath& object_path) override {
return static_cast<Properties*>(
object_map_->GetObjectProperties(object_path));
}
// NfcAdapterClient override.
void StartPollLoop(
const dbus::ObjectPath& object_path,
const std::string& mode,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override {
dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path);
if (!object_proxy) {
std::string error_message =
base::StringPrintf("NFC adapter with object path \"%s\" does not "
"exist.", object_path.value().c_str());
LOG(ERROR) << error_message;
error_callback.Run(nfc_client_helpers::kUnknownObjectError,
error_message);
return;
}
dbus::MethodCall method_call(nfc_adapter::kNfcAdapterInterface,
nfc_adapter::kStartPollLoop);
dbus::MessageWriter writer(&method_call);
writer.AppendString(mode);
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&nfc_client_helpers::OnSuccess, callback),
base::Bind(&nfc_client_helpers::OnError, error_callback));
}
// NfcAdapterClient override.
void StopPollLoop(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override {
dbus::ObjectProxy* object_proxy = object_map_->GetObjectProxy(object_path);
if (!object_proxy) {
std::string error_message =
base::StringPrintf("NFC adapter with object path \"%s\" does not "
"exist.", object_path.value().c_str());
LOG(ERROR) << error_message;
error_callback.Run(nfc_client_helpers::kUnknownObjectError,
error_message);
return;
}
dbus::MethodCall method_call(nfc_adapter::kNfcAdapterInterface,
nfc_adapter::kStopPollLoop);
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&nfc_client_helpers::OnSuccess, callback),
base::Bind(&nfc_client_helpers::OnError, error_callback));
}
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
VLOG(1) << "Creating NfcAdapterClientImpl";
DCHECK(bus);
bus_ = bus;
object_map_.reset(new nfc_client_helpers::DBusObjectMap(
nfc_adapter::kNfcAdapterServiceName, this, bus));
DCHECK(manager_client_);
manager_client_->AddObserver(this);
}
private:
// NfcManagerClient::Observer override.
void ManagerPropertyChanged(const std::string& property_name) override {
// Update the adapter proxies.
DCHECK(manager_client_);
NfcManagerClient::Properties* manager_properties =
manager_client_->GetProperties();
// Ignore changes to properties other than "Adapters".
if (property_name != manager_properties->adapters.name())
return;
// Update the known adapters.
VLOG(1) << "NFC adapters changed.";
const std::vector<dbus::ObjectPath>& received_adapters =
manager_properties->adapters.value();
object_map_->UpdateObjects(received_adapters);
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
NfcPropertySet* CreateProperties(dbus::ObjectProxy* object_proxy) override {
return new Properties(
object_proxy,
base::Bind(&NfcAdapterClientImpl::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectAdded(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterAdded(object_path));
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectRemoved(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterRemoved(object_path));
}
// Called by NfcPropertySet when a property value is changed, either by
// result of a signal or response to a GetAll() or Get() call.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {
VLOG(1) << "Adapter property changed; Path: " << object_path.value()
<< " Property: " << property_name;
FOR_EACH_OBSERVER(NfcAdapterClient::Observer, observers_,
AdapterPropertyChanged(object_path, property_name));
}
// We maintain a pointer to the bus to be able to request proxies for
// new NFC adapters that appear.
dbus::Bus* bus_;
// List of observers interested in event notifications.
base::ObserverList<NfcAdapterClient::Observer> observers_;
// Mapping from object paths to object proxies and properties structures that
// were already created by us.
std::unique_ptr<nfc_client_helpers::DBusObjectMap> object_map_;
// The manager client that we listen to events notifications from.
NfcManagerClient* manager_client_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcAdapterClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcAdapterClientImpl);
};
NfcAdapterClient::NfcAdapterClient() {
}
NfcAdapterClient::~NfcAdapterClient() {
}
NfcAdapterClient* NfcAdapterClient::Create(NfcManagerClient* manager_client) {
return new NfcAdapterClientImpl(manager_client);
}
} // namespace chromeos

@ -1,129 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_ADAPTER_CLIENT_H_
#define CHROMEOS_DBUS_NFC_ADAPTER_CLIENT_H_
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
class NfcManagerClient;
// NfcAdapterClient is used to communicate with objects representing local NFC
// adapters.
class CHROMEOS_EXPORT NfcAdapterClient : public DBusClient {
public:
// Structure of properties associated with an NFC adapter.
struct Properties : public NfcPropertySet {
// The adapter NFC radio mode. One of "Initiator", "Target", and "Idle".
// The NFC adapter will usually be in the "Idle" mode. The mode will change
// to "Initiator" or "Target" based on how a pairing is established with a
// remote tag or device. Read-only.
dbus::Property<std::string> mode;
// The adapter's current power state. Read-write.
dbus::Property<bool> powered;
// Indicates whether or not the adapter is currently polling for targets.
// This property is only valid when |mode| is "Initiator". Read-only.
dbus::Property<bool> polling;
// The NFC protocols that are supported by the adapter. Possible values
// are: "Felica", "MIFARE", "Jewel", "ISO-DEP", and "NFC-DEP". Read-only.
dbus::Property<std::vector<std::string> > protocols;
// The object paths of the NFC tags that are known to the local adapter.
// These are tags that have been "tapped" on the local adapter. Read-only.
dbus::Property<std::vector<dbus::ObjectPath> > tags;
// The object paths of the remote NFC devices that have been found by the
// local adapter. These are NFC adapters that were "tapped" on the local
// adapter. Read-only.
dbus::Property<std::vector<dbus::ObjectPath> > devices;
Properties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~Properties() override;
};
// Interface for observing changes from a local NFC adapter.
class Observer {
public:
virtual ~Observer() {}
// Called when a new adapter with object path |object_path| is added to the
// system.
virtual void AdapterAdded(const dbus::ObjectPath& object_path) {}
// Called when an adapter with object path |object_path| is removed from the
// system.
virtual void AdapterRemoved(const dbus::ObjectPath& object_path) {}
// Called when the adapter property with the name |property_name| on adapter
// with object path |object_path| has acquired a new value.
virtual void AdapterPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
};
~NfcAdapterClient() override;
// Adds and removes observers for events on all local bluetooth adapters.
// Check the |object_path| parameter of the observer methods to determine
// which adapter is issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the list of adapter object paths known to the system.
virtual std::vector<dbus::ObjectPath> GetAdapters() = 0;
// Obtains the properties for the adapter with object path |object_path|, any
// values should be copied if needed. A NULL pointer will be returned, if no
// adapter with the given object path is known to exist.
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
// Starts the polling loop for the adapter with object path |object_path|.
// Depending on the mode, the adapter will start polling for targets,
// listening to NFC devices, or both. The |mode| parameter should be one of
// "Initiator", "Target", or "Dual". The "Dual" mode will have the adapter
// alternate between "Initiator" and "Target" modes during the polling loop.
// For any other value, the adapter will default to "Initiator" mode.
virtual void StartPollLoop(
const dbus::ObjectPath& object_path,
const std::string& mode,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) = 0;
// Stops the polling loop for the adapter with object_path |object_path|.
virtual void StopPollLoop(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) = 0;
// Creates the instance.
static NfcAdapterClient* Create(NfcManagerClient* manager_client);
protected:
friend class NfcClientTest;
NfcAdapterClient();
private:
DISALLOW_COPY_AND_ASSIGN(NfcAdapterClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_ADAPTER_CLIENT_H_

@ -1,253 +0,0 @@
// 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/nfc_client_helpers.h"
#include "base/stl_util.h"
#include "dbus/values_util.h"
namespace chromeos {
namespace nfc_client_helpers {
const char kNoResponseError[] = "org.chromium.Error.NoResponse";
const char kUnknownObjectError[] = "org.chromium.Error.UnknownObject";
void OnSuccess(const base::Closure& callback, dbus::Response* response) {
DCHECK(response);
callback.Run();
}
void OnError(const ErrorCallback& error_callback,
dbus::ErrorResponse* response) {
// Error response has optional error message argument.
std::string error_name;
std::string error_message;
if (response) {
dbus::MessageReader reader(response);
error_name = response->GetErrorName();
reader.PopString(&error_message);
} else {
error_name = kNoResponseError;
error_message = "";
}
error_callback.Run(error_name, error_message);
}
DBusObjectMap::DBusObjectMap(const std::string& service_name,
Delegate* delegate,
dbus::Bus* bus)
: bus_(bus),
service_name_(service_name),
delegate_(delegate) {
DCHECK(bus_);
DCHECK(delegate_);
}
DBusObjectMap::~DBusObjectMap() {
// Clean up the Properties structures. We don't explicitly delete the object
// proxies, as they are owned by dbus::Bus.
for (ObjectMap::iterator iter = object_map_.begin();
iter != object_map_.end(); ++iter) {
const dbus::ObjectPath& object_path = iter->first;
ObjectPropertyPair pair = iter->second;
delegate_->ObjectRemoved(object_path);
CleanUpObjectPropertyPair(pair);
}
}
dbus::ObjectProxy* DBusObjectMap::GetObjectProxy(
const dbus::ObjectPath& object_path) {
return GetObjectPropertyPair(object_path).first;
}
NfcPropertySet* DBusObjectMap::GetObjectProperties(
const dbus::ObjectPath& object_path) {
return GetObjectPropertyPair(object_path).second;
}
void DBusObjectMap::UpdateObjects(const ObjectPathVector& object_paths) {
// This set is used to query if an object path was removed, while updating
// the removed paths below. The iterator is used as a hint to accelerate
// insertion.
std::set<dbus::ObjectPath> object_path_set;
std::set<dbus::ObjectPath>::iterator object_path_set_iter =
object_path_set.begin();
// Add all objects.
for (ObjectPathVector::const_iterator iter = object_paths.begin();
iter != object_paths.end(); ++iter) {
const dbus::ObjectPath &object_path = *iter;
AddObject(object_path);
// Neard usually returns object paths in ascending order. Give a hint here
// to make insertion amortized constant.
object_path_set_iter =
object_path_set.insert(object_path_set_iter, object_path);
}
// Remove all objects that are not in |object_paths|.
ObjectMap::const_iterator iter = object_map_.begin();
while (iter != object_map_.end()) {
// It is safe to use a const reference here, as DBusObjectMap::RemoveObject
// won't access it after the iterator becomes invalidated.
const dbus::ObjectPath &object_path = iter->first;
++iter;
if (!base::ContainsKey(object_path_set, object_path))
RemoveObject(object_path);
}
}
bool DBusObjectMap::AddObject(const dbus::ObjectPath& object_path) {
ObjectMap::iterator iter = object_map_.find(object_path);
if (iter != object_map_.end())
return false;
DCHECK(bus_);
DCHECK(delegate_);
dbus::ObjectProxy* object_proxy = bus_->GetObjectProxy(service_name_,
object_path);
// Create the properties structure.
NfcPropertySet* properties = delegate_->CreateProperties(object_proxy);
properties->ConnectSignals();
properties->GetAll();
ObjectPropertyPair object = std::make_pair(object_proxy, properties);
object_map_[object_path] = object;
VLOG(1) << "Created proxy for object with Path: " << object_path.value()
<< ", Service: " << service_name_;
delegate_->ObjectAdded(object_path);
return true;
}
void DBusObjectMap::RemoveObject(const dbus::ObjectPath& object_path) {
DCHECK(bus_);
DCHECK(delegate_);
ObjectMap::iterator iter = object_map_.find(object_path);
if (iter == object_map_.end())
return;
// Notify the delegate, so that it can perform any clean up that is
// necessary.
delegate_->ObjectRemoved(object_path);
// Clean up the object proxy and the properties structure.
ObjectPropertyPair pair = iter->second;
CleanUpObjectPropertyPair(pair);
object_map_.erase(iter);
VLOG(1) << "Object proxy removed for object path: "
<< object_path.value();
}
void DBusObjectMap::RefreshProperties(const dbus::ObjectPath& object_path) {
NfcPropertySet* properties = GetObjectProperties(object_path);
if (properties)
properties->GetAll();
}
void DBusObjectMap::RefreshAllProperties() {
for (ObjectMap::const_iterator iter = object_map_.begin();
iter != object_map_.end(); ++iter) {
const dbus::ObjectPath& object_path = iter->first;
RefreshProperties(object_path);
}
}
ObjectPathVector DBusObjectMap::GetObjectPaths() {
std::vector<dbus::ObjectPath> object_paths;
for (ObjectMap::const_iterator iter = object_map_.begin();
iter != object_map_.end(); ++iter) {
const dbus::ObjectPath& object_path = iter->first;
object_paths.push_back(object_path);
}
return object_paths;
}
DBusObjectMap::ObjectPropertyPair DBusObjectMap::GetObjectPropertyPair(
const dbus::ObjectPath& object_path) {
ObjectMap::iterator iter = object_map_.find(object_path);
if (iter != object_map_.end())
return iter->second;
return std::make_pair(static_cast<dbus::ObjectProxy*>(NULL),
static_cast<NfcPropertySet*>(NULL));
}
void DBusObjectMap::CleanUpObjectPropertyPair(const ObjectPropertyPair& pair) {
// Don't remove the object proxy. There is a bug in dbus::Bus that causes a
// crash when object proxies are removed, due to the proxy objects not being
// properly reference counted. (See crbug.com/170182 and crbug.com/328264).
NfcPropertySet* properties = pair.second;
delete properties;
}
ObjectProxyTree::ObjectProxyTree() {
}
ObjectProxyTree::~ObjectProxyTree() {
for (PathsToObjectMapsType::iterator iter = paths_to_object_maps_.begin();
iter != paths_to_object_maps_.end(); ++iter) {
DBusObjectMap* object_map = iter->second;
delete object_map;
}
}
bool ObjectProxyTree::CreateObjectMap(const dbus::ObjectPath& object_path,
const std::string& service_name,
DBusObjectMap::Delegate* delegate,
dbus::Bus* bus) {
if (base::ContainsKey(paths_to_object_maps_, object_path)) {
LOG(ERROR) << "Mapping already exists for object path: "
<< object_path.value();
return false;
}
paths_to_object_maps_[object_path] =
new DBusObjectMap(service_name, delegate, bus);
return true;
}
void ObjectProxyTree::RemoveObjectMap(const dbus::ObjectPath& object_path) {
PathsToObjectMapsType::iterator iter =
paths_to_object_maps_.find(object_path);
if (iter == paths_to_object_maps_.end())
return;
DBusObjectMap* object_map = iter->second;
paths_to_object_maps_.erase(iter);
delete object_map;
}
DBusObjectMap* ObjectProxyTree::GetObjectMap(
const dbus::ObjectPath& object_path) {
PathsToObjectMapsType::iterator iter =
paths_to_object_maps_.find(object_path);
if (iter == paths_to_object_maps_.end())
return NULL;
return iter->second;
}
dbus::ObjectProxy* ObjectProxyTree::FindObjectProxy(
const dbus::ObjectPath& object_proxy_path) {
for (PathsToObjectMapsType::iterator iter = paths_to_object_maps_.begin();
iter != paths_to_object_maps_.end(); ++iter) {
DBusObjectMap* object_map = iter->second;
dbus::ObjectProxy* object_proxy =
object_map->GetObjectProxy(object_proxy_path);
if (object_proxy)
return object_proxy;
}
return NULL;
}
NfcPropertySet* ObjectProxyTree::FindObjectProperties(
const dbus::ObjectPath& object_proxy_path) {
for (PathsToObjectMapsType::iterator iter = paths_to_object_maps_.begin();
iter != paths_to_object_maps_.end(); ++iter) {
DBusObjectMap* object_map = iter->second;
NfcPropertySet* properties =
object_map->GetObjectProperties(object_proxy_path);
if (properties)
return properties;
}
return NULL;
}
} // namespace nfc_client_helpers
} // namespace chromeos

@ -1,206 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_
#define CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_
#include <map>
#include <string>
#include <utility>
#include "base/callback.h"
#include "base/macros.h"
#include "base/values.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
namespace chromeos {
namespace nfc_client_helpers {
// Constants used to indicate exceptional error conditions.
CHROMEOS_EXPORT extern const char kNoResponseError[];
CHROMEOS_EXPORT extern const char kUnknownObjectError[];
// The ErrorCallback is used by D-Bus methods to indicate failure.
// It receives two arguments: the name of the error in |error_name| and
// an optional message in |error_message|.
typedef base::Callback<void(const std::string& error_name,
const std::string& error_message)> ErrorCallback;
// A vector of object paths is used frequently among the NFC client classes.
// This typedef makes the type specifier a little less verbose.
typedef std::vector<dbus::ObjectPath> ObjectPathVector;
// Called when a response for a successful method call is received.
CHROMEOS_EXPORT void OnSuccess(const base::Closure& callback,
dbus::Response* response);
// Extracts the error data from |response| and invokes |error_callback| with
// the resulting error name and error message.
CHROMEOS_EXPORT void OnError(const ErrorCallback& error_callback,
dbus::ErrorResponse* response);
// DBusObjectMap is a simple data structure that facilitates keeping track of
// D-Bus object proxies and properties. It maintains a mapping from object
// paths to object proxy - property structure pairs.
// TODO(armansito): This is only needed until neard implements the D-Bus
// org.freedesktop.DBus.ObjectManager interface. Remove this once we upgrade
// to neard-0.14.
class CHROMEOS_EXPORT DBusObjectMap {
public:
// DBusObjectMap::Delegate must be implemented by classes that use an
// instance of DBusObjectMap to manage object proxies.
class Delegate {
public:
virtual ~Delegate() {}
// Called by DBusObjectMap to create a Properties structure for the remote
// D-Bus object accessible through |object_proxy|. The implementation class
// should create and return an instance of its own subclass of
// ::chromeos::NfcPropertySet. DBusObjectMap will handle connecting the
// signals and update the properties.
virtual NfcPropertySet* CreateProperties(
dbus::ObjectProxy* object_proxy) = 0;
// Notifies the delegate that an object was added with object path
// |object_path|.
virtual void ObjectAdded(const dbus::ObjectPath& object_path) {}
// Notifies the delegate that an object was removed with object path
// |object_path|. The object proxy will still be valid before this method
// returns, so that delegates can perform any clean up that use the object
// properties. Note that the remote object will no longer be available,
// but the delegates can still access the cached properties of the object.
virtual void ObjectRemoved(const dbus::ObjectPath& object_path) {}
};
// Constructor takes in the D-Bus service name the proxies belong to and
// the delegate which will be used to construct properties structures.
// |service_name| must be a valid D-Bus service name, and |delegate| cannot
// be NULL.
DBusObjectMap(const std::string& service_name,
Delegate* delegate,
dbus::Bus* bus);
// Destructor destroys all managed object proxies and notifies the delegate
// for each removed object.
virtual ~DBusObjectMap();
// Returns the object proxy for object path |object_path|. If no object proxy
// exists for |object_path|, returns NULL.
dbus::ObjectProxy* GetObjectProxy(const dbus::ObjectPath& object_path);
// Returns the properties structure for remote object with object path
// |object_path|. If no properties structure exists for |object_path|,
// returns NULL.
NfcPropertySet* GetObjectProperties(const dbus::ObjectPath& object_path);
// Updates the object proxies from the given list of object paths
// |object_paths|. It notifies the delegate of each added and removed object
// via |Delegate::ObjectAdded| and |Delegate::ObjectRemoved|.
void UpdateObjects(const ObjectPathVector& object_paths);
// Creates and stores an object proxy and properties structure for a remote
// object with object path |object_path|. If an object proxy was already
// created, this operation returns false; returns true otherwise.
bool AddObject(const dbus::ObjectPath& object_path);
// Removes the D-Bus object proxy and the properties structure for the
// remote object with object path |object_path|. If no known proxy for
// |object_path| exists, then this operation is a no-op.
void RemoveObject(const dbus::ObjectPath& object_path);
// Invokes GetAll on the property structure belonging to object path
// |object_path|. If |object_path| is unknown, this method is a no-op.
void RefreshProperties(const dbus::ObjectPath& object_path);
// Invokes GetAll on the property structures belonging to all object paths
// that are managed by this instance.
void RefreshAllProperties();
// Returns a list containing the object paths of all remote objects that are
// managed by this instance.
ObjectPathVector GetObjectPaths();
private:
typedef std::pair<dbus::ObjectProxy*, NfcPropertySet*> ObjectPropertyPair;
typedef std::map<dbus::ObjectPath, ObjectPropertyPair> ObjectMap;
// Returns an instance of ObjectPropertyPair by looking up |object_path| in
// |object_map_|. If no entry is found, returns an instance that contains
// NULL pointers.
ObjectPropertyPair GetObjectPropertyPair(const dbus::ObjectPath& object_path);
// Cleans up the object proxy and properties structure in |pair|. This method
// will remove the object proxy by calling |dbus::Bus::RemoveObjectProxy| and
// explicitly deallocate the properties structure. Once this method exits,
// both pointers stored by |pair| will become invalid and should not be used.
// If |pair| contains invalid pointers at the time when this method is called
// memory errors are likely to happen, so only valid pointers should be
// passed.
void CleanUpObjectPropertyPair(const ObjectPropertyPair& pair);
dbus::Bus* bus_;
ObjectMap object_map_;
std::string service_name_;
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(DBusObjectMap);
};
// Most NFC D-Bus client classes need to be able to look up object proxies by
// the path of the object that owns them. For example, NfcTagClient updates tag
// proxies based on the adapter that owns them. ObjectProxyTree is a two-level
// mapping that makes this management easy.
class ObjectProxyTree {
public:
ObjectProxyTree();
// The destructor destroys all contained DBusObjectMap instances. This will
// cause the delegate to get notified for each removed object proxy according
// to the DBusObjectMap destructor.
virtual ~ObjectProxyTree();
// Creates a DBusObjectMap instance at object path |object_path|.
// |service_name|, |delegate|, and |bus| are passed to the constructor of the
// DBusObjectMap that is created. If a DBusObjectMap for |object_path| was
// already assigned, returns false and does nothing. Otherwise, if a new
// DBusObjectMap was created, returns true.
bool CreateObjectMap(const dbus::ObjectPath& object_path,
const std::string& service_name,
DBusObjectMap::Delegate* delegate,
dbus::Bus* bus);
// Destroys the DBusObjectMap instance at object path |object_path|.
void RemoveObjectMap(const dbus::ObjectPath& object_path);
// Returns the DBusObjectMap instance at object path |object_path|, or NULL
// if no such instance exists.
DBusObjectMap* GetObjectMap(const dbus::ObjectPath& object_path);
// Returns the object proxy by searching all stored DBusObjectMap instances
// for |object_proxy_path|. Returns NULL, if nothing is found.
dbus::ObjectProxy* FindObjectProxy(
const dbus::ObjectPath& object_proxy_path);
// Returns the object property structure by searching all stored DBusObjectMap
// instances for |object_proxy_path|. Returns NULL, if nothing is found.
NfcPropertySet* FindObjectProperties(
const dbus::ObjectPath& object_proxy_path);
private:
typedef std::map<dbus::ObjectPath, DBusObjectMap*> PathsToObjectMapsType;
PathsToObjectMapsType paths_to_object_maps_;
DISALLOW_COPY_AND_ASSIGN(ObjectProxyTree);
};
} // namespace nfc_client_helpers
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_CLIENT_HELPERS_H_

@ -1,898 +0,0 @@
// 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 <stddef.h>
#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_manager_client.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using ::testing::_;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;
using chromeos::nfc_client_helpers::ObjectPathVector;
namespace chromeos {
namespace {
// D-Bus service name used by the test.
const char kTestServiceName[] = "test.service.name";
// Object paths that are used for testing.
const char kTestManagerPath[] = "/test/nfc/manager";
const char kTestAdapterPath0[] = "/test/nfc/adapter0";
const char kTestAdapterPath1[] = "/test/nfc/adapter1";
const char kTestDevicePath0[] = "/test/nfc/device0";
const char kTestDevicePath1[] = "/test/nfc/device1";
const char kTestRecordPath0[] = "/test/nfc/record0";
const char kTestRecordPath1[] = "/test/nfc/record1";
const char kTestRecordPath2[] = "/test/nfc/record2";
const char kTestRecordPath3[] = "/test/nfc/record3";
const char kTestTagPath0[] = "/test/nfc/tag0";
const char kTestTagPath1[] = "/test/nfc/tag1";
class MockNfcManagerObserver : public NfcManagerClient::Observer {
public:
MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&));
MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&));
MOCK_METHOD1(ManagerPropertyChanged, void(const std::string&));
};
class MockNfcAdapterObserver : public NfcAdapterClient::Observer {
public:
MOCK_METHOD1(AdapterAdded, void(const dbus::ObjectPath&));
MOCK_METHOD1(AdapterRemoved, void(const dbus::ObjectPath&));
MOCK_METHOD2(AdapterPropertyChanged, void(const dbus::ObjectPath&,
const std::string&));
};
class MockNfcDeviceObserver : public NfcDeviceClient::Observer {
public:
MOCK_METHOD1(DeviceAdded, void(const dbus::ObjectPath&));
MOCK_METHOD1(DeviceRemoved, void(const dbus::ObjectPath&));
MOCK_METHOD2(DevicePropertyChanged, void(const dbus::ObjectPath&,
const std::string&));
};
class MockNfcRecordObserver : public NfcRecordClient::Observer {
public:
MOCK_METHOD1(RecordAdded, void(const dbus::ObjectPath&));
MOCK_METHOD1(RecordRemoved, void(const dbus::ObjectPath&));
MOCK_METHOD2(RecordPropertyChanged, void(const dbus::ObjectPath&,
const std::string&));
MOCK_METHOD1(RecordPropertiesReceived, void(const dbus::ObjectPath&));
};
class MockNfcTagObserver : public NfcTagClient::Observer {
public:
MOCK_METHOD1(TagAdded, void(const dbus::ObjectPath&));
MOCK_METHOD1(TagRemoved, void(const dbus::ObjectPath&));
MOCK_METHOD2(TagPropertyChanged, void(const dbus::ObjectPath&,
const std::string&));
};
} // namespace
class NfcClientTest : public testing::Test {
public:
NfcClientTest() : response_(NULL) {}
~NfcClientTest() override {}
void SetUp() override {
// Create the mock bus.
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
mock_bus_ = new dbus::MockBus(options);
// Create the mock proxies.
mock_manager_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestManagerPath));
mock_adapter0_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestAdapterPath0));
mock_adapter1_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestAdapterPath1));
mock_device0_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestDevicePath0));
mock_device1_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestDevicePath1));
mock_record0_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestRecordPath0));
mock_record1_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestRecordPath1));
mock_record2_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestRecordPath2));
mock_record3_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestRecordPath3));
mock_tag0_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestTagPath0));
mock_tag1_proxy_ = new dbus::MockObjectProxy(
mock_bus_.get(),
kTestServiceName,
dbus::ObjectPath(kTestTagPath1));
// Set expectations that use NfcClientTest::OnConnectToSignal when the
// client connect signals on the mock proxies.
EXPECT_CALL(*mock_manager_proxy_.get(), ConnectToSignal(_, _, _, _))
.WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal));
EXPECT_CALL(*mock_adapter0_proxy_.get(), ConnectToSignal(_, _, _, _))
.WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal));
EXPECT_CALL(*mock_adapter1_proxy_.get(), ConnectToSignal(_, _, _, _))
.WillRepeatedly(Invoke(this, &NfcClientTest::OnConnectToSignal));
// Set expectations that return our mock proxies on demand.
EXPECT_CALL(
*mock_bus_.get(),
GetObjectProxy(nfc_manager::kNfcManagerServiceName,
dbus::ObjectPath(nfc_manager::kNfcManagerServicePath)))
.WillRepeatedly(Return(mock_manager_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_adapter::kNfcAdapterServiceName,
dbus::ObjectPath(kTestAdapterPath0)))
.WillRepeatedly(Return(mock_adapter0_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_adapter::kNfcAdapterServiceName,
dbus::ObjectPath(kTestAdapterPath1)))
.WillRepeatedly(Return(mock_adapter1_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_device::kNfcDeviceServiceName,
dbus::ObjectPath(kTestDevicePath0)))
.WillRepeatedly(Return(mock_device0_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_device::kNfcDeviceServiceName,
dbus::ObjectPath(kTestDevicePath1)))
.WillRepeatedly(Return(mock_device1_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_record::kNfcRecordServiceName,
dbus::ObjectPath(kTestRecordPath0)))
.WillRepeatedly(Return(mock_record0_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_record::kNfcRecordServiceName,
dbus::ObjectPath(kTestRecordPath1)))
.WillRepeatedly(Return(mock_record1_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_record::kNfcRecordServiceName,
dbus::ObjectPath(kTestRecordPath2)))
.WillRepeatedly(Return(mock_record2_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_record::kNfcRecordServiceName,
dbus::ObjectPath(kTestRecordPath3)))
.WillRepeatedly(Return(mock_record3_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_tag::kNfcTagServiceName,
dbus::ObjectPath(kTestTagPath0)))
.WillRepeatedly(Return(mock_tag0_proxy_.get()));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(nfc_tag::kNfcTagServiceName,
dbus::ObjectPath(kTestTagPath1)))
.WillRepeatedly(Return(mock_tag1_proxy_.get()));
// Handle |manager_client_|'s request to register a callback
// for |mock_manager_proxy_|'s D-Bus service becoming available.
EXPECT_CALL(*mock_manager_proxy_.get(), WaitForServiceToBeAvailable(_))
.WillRepeatedly(
Invoke(this, &NfcClientTest::OnWaitForServiceToBeAvailable));
// ShutdownAndBlock will be called in TearDown.
EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
// Create the clients.
manager_client_.reset(NfcManagerClient::Create());
adapter_client_.reset(NfcAdapterClient::Create(manager_client_.get()));
device_client_.reset(NfcDeviceClient::Create(adapter_client_.get()));
tag_client_.reset(NfcTagClient::Create(adapter_client_.get()));
record_client_.reset(
NfcRecordClient::Create(device_client_.get(), tag_client_.get()));
manager_client_->Init(mock_bus_.get());
adapter_client_->Init(mock_bus_.get());
device_client_->Init(mock_bus_.get());
tag_client_->Init(mock_bus_.get());
record_client_->Init(mock_bus_.get());
manager_client_->AddObserver(&mock_manager_observer_);
adapter_client_->AddObserver(&mock_adapter_observer_);
device_client_->AddObserver(&mock_device_observer_);
tag_client_->AddObserver(&mock_tag_observer_);
record_client_->AddObserver(&mock_record_observer_);
message_loop_.RunUntilIdle();
}
void TearDown() override {
tag_client_->RemoveObserver(&mock_tag_observer_);
device_client_->RemoveObserver(&mock_device_observer_);
adapter_client_->RemoveObserver(&mock_adapter_observer_);
manager_client_->RemoveObserver(&mock_manager_observer_);
mock_bus_->ShutdownAndBlock();
}
void SimulateAdaptersChanged(
const ObjectPathVector& adapter_paths) {
NfcManagerClient::Properties* properties =
manager_client_->GetProperties();
ASSERT_TRUE(properties);
EXPECT_CALL(mock_manager_observer_,
ManagerPropertyChanged(nfc_manager::kAdaptersProperty));
SendArrayPropertyChangedSignal(
properties,
nfc_manager::kNfcManagerInterface,
nfc_manager::kAdaptersProperty,
adapter_paths);
Mock::VerifyAndClearExpectations(&mock_manager_observer_);
}
void SimulateTagsChanged(const ObjectPathVector& tag_paths,
const dbus::ObjectPath& adapter_path) {
NfcAdapterClient::Properties* properties =
adapter_client_->GetProperties(adapter_path);
ASSERT_TRUE(properties);
EXPECT_CALL(mock_adapter_observer_,
AdapterPropertyChanged(adapter_path,
nfc_adapter::kTagsProperty));
SendArrayPropertyChangedSignal(
properties,
nfc_adapter::kNfcAdapterInterface,
nfc_adapter::kTagsProperty,
tag_paths);
Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
}
void SimulateDevicesChanged(const ObjectPathVector& device_paths,
const dbus::ObjectPath& adapter_path) {
NfcAdapterClient::Properties* properties =
adapter_client_->GetProperties(adapter_path);
ASSERT_TRUE(properties);
EXPECT_CALL(mock_adapter_observer_,
AdapterPropertyChanged(adapter_path,
nfc_adapter::kDevicesProperty));
SendArrayPropertyChangedSignal(
properties,
nfc_adapter::kNfcAdapterInterface,
nfc_adapter::kDevicesProperty,
device_paths);
Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
}
void SimulateDeviceRecordsChanged(
const ObjectPathVector& record_paths,
const dbus::ObjectPath& device_path) {
NfcDeviceClient::Properties* properties =
device_client_->GetProperties(device_path);
ASSERT_TRUE(properties);
EXPECT_CALL(mock_device_observer_,
DevicePropertyChanged(device_path,
nfc_device::kRecordsProperty));
SendArrayPropertyChangedSignal(
properties,
nfc_device::kNfcDeviceInterface,
nfc_device::kRecordsProperty,
record_paths);
Mock::VerifyAndClearExpectations(&mock_device_observer_);
}
void SimulateTagRecordsChanged(
const ObjectPathVector& record_paths,
const dbus::ObjectPath& tag_path) {
NfcTagClient::Properties* properties =
tag_client_->GetProperties(tag_path);
ASSERT_TRUE(properties);
EXPECT_CALL(mock_tag_observer_,
TagPropertyChanged(tag_path,
nfc_tag::kRecordsProperty));
SendArrayPropertyChangedSignal(
properties,
nfc_tag::kNfcTagInterface,
nfc_tag::kRecordsProperty,
record_paths);
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
}
void SendArrayPropertyChangedSignal(
dbus::PropertySet* properties,
const std::string& interface,
const std::string& property_name,
ObjectPathVector object_paths) {
dbus::Signal signal(interface, nfc_common::kPropertyChangedSignal);
dbus::MessageWriter writer(&signal);
writer.AppendString(property_name);
dbus::MessageWriter variant_writer(NULL);
writer.OpenVariant("ao", &variant_writer);
variant_writer.AppendArrayOfObjectPaths(object_paths);
writer.CloseContainer(&variant_writer);
properties->ChangedReceived(&signal);
}
MOCK_METHOD0(SuccessCallback, void(void));
MOCK_METHOD2(ErrorCallback, void(const std::string& error_name,
const std::string& error_message));
protected:
// The mock object proxies.
scoped_refptr<dbus::MockObjectProxy> mock_manager_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_adapter0_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_adapter1_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_device0_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_device1_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_record0_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_record1_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_record2_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_record3_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_tag0_proxy_;
scoped_refptr<dbus::MockObjectProxy> mock_tag1_proxy_;
// The mock bus.
scoped_refptr<dbus::MockBus> mock_bus_;
// A message loop to emulate asynchronous behavior.
base::MessageLoop message_loop_;
// Response returned by mock methods.
dbus::Response* response_;
// The D-Bus client objects under test.
std::unique_ptr<NfcManagerClient> manager_client_;
std::unique_ptr<NfcAdapterClient> adapter_client_;
std::unique_ptr<NfcDeviceClient> device_client_;
std::unique_ptr<NfcTagClient> tag_client_;
std::unique_ptr<NfcRecordClient> record_client_;
// Mock observers.
MockNfcManagerObserver mock_manager_observer_;
MockNfcAdapterObserver mock_adapter_observer_;
MockNfcDeviceObserver mock_device_observer_;
MockNfcTagObserver mock_tag_observer_;
MockNfcRecordObserver mock_record_observer_;
// The signal callbacks used to simulate asychronous signals.
dbus::ObjectProxy::SignalCallback manager_adapter_added_signal_callback_;
dbus::ObjectProxy::SignalCallback manager_adapter_removed_signal_callback_;
private:
// Used to inform |manager_client_| that |mock_manager_proxy_| is ready.
void OnWaitForServiceToBeAvailable(
dbus::ObjectProxy::WaitForServiceToBeAvailableCallback callback) {
message_loop_.task_runner()->PostTask(FROM_HERE,
base::Bind(callback, true));
}
// Used to implement the mock proxy.
void OnConnectToSignal(
const std::string& interface_name,
const std::string& signal_name,
const dbus::ObjectProxy::SignalCallback& signal_callback,
const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
if (interface_name == nfc_manager::kNfcManagerInterface) {
if (signal_name == nfc_manager::kAdapterAddedSignal)
manager_adapter_added_signal_callback_ = signal_callback;
else if (signal_name == nfc_manager::kAdapterRemovedSignal)
manager_adapter_removed_signal_callback_ = signal_callback;
}
message_loop_.task_runner()->PostTask(
FROM_HERE,
base::Bind(on_connected_callback, interface_name, signal_name, true));
}
};
// Tests that when adapters are added and removed through the manager, all
// observers are notified and the proxies are created and removed
// accordingly.
TEST_F(NfcClientTest, AdaptersAddedAndRemoved) {
// Invoking methods on adapters that haven't been added should fail.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
// Add adapter 0.
ObjectPathVector adapter_paths;
adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0));
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
SimulateAdaptersChanged(adapter_paths);
// Invoking methods should succeed on adapter 0 but fail on adapter 1.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(1);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Add adapter 1.
adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath1));
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
SimulateAdaptersChanged(adapter_paths);
// Invoking methods should succeed on both adapters.
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 0.
adapter_paths.erase(adapter_paths.begin());
EXPECT_CALL(mock_adapter_observer_,
AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
SimulateAdaptersChanged(adapter_paths);
// Invoking methods should succeed on adapter 1 but fail on adapter 0.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_adapter0_proxy_);
Mock::VerifyAndClearExpectations(&mock_adapter1_proxy_);
// Remove adapter 1.
adapter_paths.clear();
EXPECT_CALL(mock_adapter_observer_,
AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
SimulateAdaptersChanged(adapter_paths);
// Invoking methods should fail on both adapters.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
.Times(2);
EXPECT_CALL(*mock_adapter0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
EXPECT_CALL(*mock_adapter1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
adapter_client_->StartPollLoop(
dbus::ObjectPath(kTestAdapterPath1),
nfc_adapter::kModeInitiator,
base::Bind(&NfcClientTest::SuccessCallback, base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback, base::Unretained(this)));
}
// Tests that when tags are added and removed through an adapter, all
// observers are notified and the proxies are created and removed
// accordingly.
TEST_F(NfcClientTest, TagsAddedAndRemoved) {
// Invoking methods on tags that haven't been added should fail.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
base::DictionaryValue write_data;
write_data.SetString(nfc_record::kTypeProperty, nfc_record::kTypeText);
tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
// Add adapter 0.
ObjectPathVector adapter_paths;
adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0));
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
SimulateAdaptersChanged(adapter_paths);
Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
// Add tag 0.
ObjectPathVector tag_paths;
tag_paths.push_back(dbus::ObjectPath(kTestTagPath0));
EXPECT_CALL(mock_tag_observer_,
TagAdded(dbus::ObjectPath(kTestTagPath0)));
SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
// Invoking methods should succeed on tag 0 but fail on tag 1.
EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(1);
tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
// Add tag 1.
tag_paths.push_back(dbus::ObjectPath(kTestTagPath1));
EXPECT_CALL(mock_tag_observer_,
TagAdded(dbus::ObjectPath(kTestTagPath1)));
SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
// Invoking methods should succeed on both tags.
EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
// Remove tag 0.
tag_paths.erase(tag_paths.begin());
EXPECT_CALL(mock_tag_observer_,
TagRemoved(dbus::ObjectPath(kTestTagPath0)));
SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
// Invoking methods should succeed on tag 1 but fail on tag 0.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
Mock::VerifyAndClearExpectations(&mock_tag0_proxy_);
EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_tag1_proxy_);
// Remove tag 1.
tag_paths.clear();
EXPECT_CALL(mock_tag_observer_,
TagRemoved(dbus::ObjectPath(kTestTagPath1)));
SimulateTagsChanged(tag_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
// Invoking methods should fail on both tags.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
.Times(2);
EXPECT_CALL(*mock_tag0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
EXPECT_CALL(*mock_tag1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
tag_client_->Write(dbus::ObjectPath(kTestTagPath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
tag_client_->Write(dbus::ObjectPath(kTestTagPath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
}
// Tests that when devices are added and removed through an adapter, all
// observers are notified and the proxies are created and removed
// accordingly.
TEST_F(NfcClientTest, DevicesAddedAndRemoved) {
// Invoking methods on devices that haven't been added should fail.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
base::DictionaryValue write_data;
write_data.SetString(nfc_record::kTypeProperty, nfc_record::kTypeText);
device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
// Add adapter 0.
ObjectPathVector adapter_paths;
adapter_paths.push_back(dbus::ObjectPath(kTestAdapterPath0));
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
SimulateAdaptersChanged(adapter_paths);
// Add device 0.
ObjectPathVector device_paths;
device_paths.push_back(dbus::ObjectPath(kTestDevicePath0));
EXPECT_CALL(mock_device_observer_,
DeviceAdded(dbus::ObjectPath(kTestDevicePath0)));
SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_device_observer_);
// Invoking methods should succeed on device 0 but fail on device 1.
EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(1);
device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
// Add device 1.
device_paths.push_back(dbus::ObjectPath(kTestDevicePath1));
EXPECT_CALL(mock_device_observer_,
DeviceAdded(dbus::ObjectPath(kTestDevicePath1)));
SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_device_observer_);
// Invoking methods should succeed on both devices.
EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _));
EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
// Remove device 0.
device_paths.erase(device_paths.begin());
EXPECT_CALL(mock_device_observer_,
DeviceRemoved(dbus::ObjectPath(kTestDevicePath0)));
SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_device_observer_);
// Invoking methods should succeed on device 1 but fail on device 0.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _));
EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(this);
Mock::VerifyAndClearExpectations(&mock_device0_proxy_);
EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _));
device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
Mock::VerifyAndClearExpectations(&mock_device1_proxy_);
// Remove device 1.
device_paths.clear();
EXPECT_CALL(mock_device_observer_,
DeviceRemoved(dbus::ObjectPath(kTestDevicePath1)));
SimulateDevicesChanged(device_paths, dbus::ObjectPath(kTestAdapterPath0));
Mock::VerifyAndClearExpectations(&mock_device_observer_);
// Invoking methods should fail on both devices.
EXPECT_CALL(*this,
ErrorCallback(nfc_client_helpers::kUnknownObjectError, _))
.Times(2);
EXPECT_CALL(*mock_device0_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
EXPECT_CALL(*mock_device1_proxy_, CallMethodWithErrorCallback(_, _, _, _))
.Times(0);
device_client_->Push(dbus::ObjectPath(kTestDevicePath0), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
device_client_->Push(dbus::ObjectPath(kTestDevicePath1), write_data,
base::Bind(&NfcClientTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcClientTest::ErrorCallback,
base::Unretained(this)));
}
TEST_F(NfcClientTest, ObjectCleanup) {
// Tests that when an adapter gets removed, proxies that belong to the
// adapter, device, tag, and record hierarchy get cleaned up properly.
ObjectPathVector object_paths;
// Add adapters.
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath0)));
EXPECT_CALL(mock_adapter_observer_,
AdapterAdded(dbus::ObjectPath(kTestAdapterPath1)));
object_paths.push_back(dbus::ObjectPath(kTestAdapterPath0));
object_paths.push_back(dbus::ObjectPath(kTestAdapterPath1));
SimulateAdaptersChanged(object_paths);
Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
// Add devices and a tags. Assign them like the following:
// - device 0 -> adapter 0
// - tag 0 -> adapter 0
// - device 1 -> adapter 1
// - tag 1 -> adapter 1
EXPECT_CALL(mock_device_observer_,
DeviceAdded(dbus::ObjectPath(kTestDevicePath0)));
EXPECT_CALL(mock_device_observer_,
DeviceAdded(dbus::ObjectPath(kTestDevicePath1)));
EXPECT_CALL(mock_tag_observer_,
TagAdded(dbus::ObjectPath(kTestTagPath0)));
EXPECT_CALL(mock_tag_observer_,
TagAdded(dbus::ObjectPath(kTestTagPath1)));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestDevicePath0));
SimulateDevicesChanged(object_paths, dbus::ObjectPath(kTestAdapterPath0));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestTagPath0));
SimulateTagsChanged(object_paths, dbus::ObjectPath(kTestAdapterPath0));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestDevicePath1));
SimulateDevicesChanged(object_paths, dbus::ObjectPath(kTestAdapterPath1));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestTagPath1));
SimulateTagsChanged(object_paths, dbus::ObjectPath(kTestAdapterPath1));
Mock::VerifyAndClearExpectations(&mock_device_observer_);
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
// Add records. Assign them like the following:
// - record 0 -> device 0
// - record 1 -> tag 0
// - record 2 -> device 1
// - record 3 -> tag 1
EXPECT_CALL(mock_record_observer_,
RecordAdded(dbus::ObjectPath(kTestRecordPath0)));
EXPECT_CALL(mock_record_observer_,
RecordAdded(dbus::ObjectPath(kTestRecordPath1)));
EXPECT_CALL(mock_record_observer_,
RecordAdded(dbus::ObjectPath(kTestRecordPath2)));
EXPECT_CALL(mock_record_observer_,
RecordAdded(dbus::ObjectPath(kTestRecordPath3)));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestRecordPath0));
SimulateDeviceRecordsChanged(object_paths,
dbus::ObjectPath(kTestDevicePath0));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestRecordPath1));
SimulateTagRecordsChanged(object_paths,
dbus::ObjectPath(kTestTagPath0));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestRecordPath2));
SimulateDeviceRecordsChanged(object_paths,
dbus::ObjectPath(kTestDevicePath1));
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestRecordPath3));
SimulateTagRecordsChanged(object_paths,
dbus::ObjectPath(kTestTagPath1));
Mock::VerifyAndClearExpectations(&mock_record_observer_);
// Check that the records have been assigned to the correct device or tag.
NfcTagClient::Properties* tag_properties =
tag_client_->GetProperties(dbus::ObjectPath(kTestTagPath0));
EXPECT_EQ((size_t)1, tag_properties->records.value().size());
EXPECT_EQ(dbus::ObjectPath(kTestRecordPath1),
tag_properties->records.value()[0]);
NfcDeviceClient::Properties* device_properties =
device_client_->GetProperties(dbus::ObjectPath(kTestDevicePath0));
EXPECT_EQ((size_t)1, device_properties->records.value().size());
EXPECT_EQ(dbus::ObjectPath(kTestRecordPath0),
device_properties->records.value()[0]);
// Remove adapter 0. Make sure that all of the tag, device, and records that
// are in the adapter 0 hierarchy are removed.
object_paths.clear();
object_paths.push_back(dbus::ObjectPath(kTestAdapterPath1));
EXPECT_CALL(mock_adapter_observer_,
AdapterRemoved(dbus::ObjectPath(kTestAdapterPath0)));
EXPECT_CALL(mock_device_observer_,
DeviceRemoved(dbus::ObjectPath(kTestDevicePath0)));
EXPECT_CALL(mock_tag_observer_,
TagRemoved(dbus::ObjectPath(kTestTagPath0)));
EXPECT_CALL(mock_record_observer_,
RecordRemoved(dbus::ObjectPath(kTestRecordPath0)));
EXPECT_CALL(mock_record_observer_,
RecordRemoved(dbus::ObjectPath(kTestRecordPath1)));
SimulateAdaptersChanged(object_paths);
Mock::VerifyAndClearExpectations(&mock_adapter_observer_);
Mock::VerifyAndClearExpectations(&mock_device_observer_);
Mock::VerifyAndClearExpectations(&mock_tag_observer_);
Mock::VerifyAndClearExpectations(&mock_record_observer_);
// Remove adapter 1.
object_paths.clear();
EXPECT_CALL(mock_adapter_observer_,
AdapterRemoved(dbus::ObjectPath(kTestAdapterPath1)));
EXPECT_CALL(mock_device_observer_,
DeviceRemoved(dbus::ObjectPath(kTestDevicePath1)));
EXPECT_CALL(mock_tag_observer_,
TagRemoved(dbus::ObjectPath(kTestTagPath1)));
EXPECT_CALL(mock_record_observer_,
RecordRemoved(dbus::ObjectPath(kTestRecordPath2)));
EXPECT_CALL(mock_record_observer_,
RecordRemoved(dbus::ObjectPath(kTestRecordPath3)));
SimulateAdaptersChanged(object_paths);
}
} // namespace chromeos

@ -1,237 +0,0 @@
// 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/nfc_device_client.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/values_util.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using chromeos::nfc_client_helpers::DBusObjectMap;
using chromeos::nfc_client_helpers::ObjectProxyTree;
namespace chromeos {
NfcDeviceClient::Properties::Properties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: NfcPropertySet(object_proxy,
nfc_device::kNfcDeviceInterface,
callback) {
RegisterProperty(nfc_device::kRecordsProperty, &records);
}
NfcDeviceClient::Properties::~Properties() {
}
// The NfcDeviceClient implementation used in production.
class NfcDeviceClientImpl : public NfcDeviceClient,
public NfcAdapterClient::Observer,
public DBusObjectMap::Delegate {
public:
explicit NfcDeviceClientImpl(NfcAdapterClient* adapter_client)
: bus_(NULL),
adapter_client_(adapter_client),
weak_ptr_factory_(this) {
DCHECK(adapter_client);
}
~NfcDeviceClientImpl() override {
DCHECK(adapter_client_);
adapter_client_->RemoveObserver(this);
}
// NfcDeviceClient override.
void AddObserver(NfcDeviceClient::Observer* observer) override {
DCHECK(observer);
observers_.AddObserver(observer);
}
// NfcDeviceClient override.
void RemoveObserver(NfcDeviceClient::Observer* observer) override {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
// NfcDeviceClient override.
std::vector<dbus::ObjectPath> GetDevicesForAdapter(
const dbus::ObjectPath& adapter_path) override {
DBusObjectMap* object_map =
adapters_to_object_maps_.GetObjectMap(adapter_path);
if (!object_map)
return std::vector<dbus::ObjectPath>();
return object_map->GetObjectPaths();
}
// NfcDeviceClient override.
Properties* GetProperties(const dbus::ObjectPath& object_path) override {
return static_cast<Properties*>(
adapters_to_object_maps_.FindObjectProperties(object_path));
}
// NfcDeviceClient override.
void Push(const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override {
dbus::ObjectProxy* object_proxy =
adapters_to_object_maps_.FindObjectProxy(object_path);
if (!object_proxy) {
std::string error_message =
base::StringPrintf(
"NFC device with object path \"%s\" does not exist.",
object_path.value().c_str());
LOG(ERROR) << error_message;
error_callback.Run(nfc_client_helpers::kUnknownObjectError,
error_message);
return;
}
// |attributes| should not be empty.
if (attributes.empty()) {
std::string error_message =
"Cannot push data to device with empty arguments.";
LOG(ERROR) << error_message;
error_callback.Run(nfc_error::kInvalidArguments, error_message);
return;
}
// Create the arguments.
dbus::MethodCall method_call(nfc_device::kNfcDeviceInterface,
nfc_device::kPush);
dbus::MessageWriter writer(&method_call);
dbus::AppendValueData(&writer, attributes);
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&nfc_client_helpers::OnSuccess, callback),
base::Bind(&nfc_client_helpers::OnError, error_callback));
}
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
VLOG(1) << "Creating NfcDeviceClientImpl";
DCHECK(bus);
bus_ = bus;
DCHECK(adapter_client_);
adapter_client_->AddObserver(this);
}
private:
// NfcAdapterClient::Observer override.
void AdapterAdded(const dbus::ObjectPath& object_path) override {
VLOG(1) << "Adapter added. Creating map for device proxies belonging to "
<< "adapter: " << object_path.value();
adapters_to_object_maps_.CreateObjectMap(
object_path, nfc_device::kNfcDeviceServiceName, this, bus_);
}
// NfcAdapterClient::Observer override.
void AdapterRemoved(const dbus::ObjectPath& object_path) override {
// Neard doesn't send out property changed signals for the devices that
// are removed when the adapter they belong to is removed. Clean up the
// object proxies for devices that are managed by the removed adapter.
// Note: DBusObjectMap guarantees that the Properties structure for the
// removed adapter will be valid before this method returns.
VLOG(1) << "Adapter removed. Cleaning up device proxies belonging to "
<< "adapter: " << object_path.value();
adapters_to_object_maps_.RemoveObjectMap(object_path);
}
// NfcAdapterClient::Observer override.
void AdapterPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override {
DCHECK(adapter_client_);
NfcAdapterClient::Properties *adapter_properties =
adapter_client_->GetProperties(object_path);
DCHECK(adapter_properties);
// Ignore changes to properties other than "Devices".
if (property_name != adapter_properties->devices.name())
return;
// Update the known devices.
VLOG(1) << "NFC devices changed.";
const std::vector<dbus::ObjectPath>& received_devices =
adapter_properties->devices.value();
DBusObjectMap* object_map =
adapters_to_object_maps_.GetObjectMap(object_path);
DCHECK(object_map);
object_map->UpdateObjects(received_devices);
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
NfcPropertySet* CreateProperties(dbus::ObjectProxy* object_proxy) override {
return new Properties(
object_proxy,
base::Bind(&NfcDeviceClientImpl::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectAdded(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
DeviceAdded(object_path));
}
void ObjectRemoved(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
DeviceRemoved(object_path));
}
// Called by NfcPropertySet when a property value is changed, either by
// result of a signal or response to a GetAll() or Get() call.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {
VLOG(1) << "Device property changed; Path: " << object_path.value()
<< " Property: " << property_name;
FOR_EACH_OBSERVER(NfcDeviceClient::Observer, observers_,
DevicePropertyChanged(object_path, property_name));
}
// We maintain a pointer to the bus to be able to request proxies for
// new NFC devices that appear.
dbus::Bus* bus_;
// List of observers interested in event notifications.
base::ObserverList<NfcDeviceClient::Observer> observers_;
// Mapping from object paths to object proxies and properties structures that
// were already created by us. This stucture stores a different DBusObjectMap
// for each known NFC adapter object path.
ObjectProxyTree adapters_to_object_maps_;
// The adapter client that we listen to events notifications from.
NfcAdapterClient* adapter_client_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcDeviceClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcDeviceClientImpl);
};
NfcDeviceClient::NfcDeviceClient() {
}
NfcDeviceClient::~NfcDeviceClient() {
}
NfcDeviceClient* NfcDeviceClient::Create(NfcAdapterClient* adapter_client) {
return new NfcDeviceClientImpl(adapter_client);
}
} // namespace chromeos

@ -1,118 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_
#define CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_
#include <map>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/values.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
class NfcAdapterClient;
// NfcDeviceClient is used to communicate with objects representing remote NFC
// devices that can be communicated with.
class CHROMEOS_EXPORT NfcDeviceClient : public DBusClient {
public:
// Structure of properties associated with an NFC device.
struct Properties : public NfcPropertySet {
// List of object paths for NDEF records associated with the NFC device.
// Read-only.
dbus::Property<std::vector<dbus::ObjectPath> > records;
Properties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~Properties() override;
};
// Interface for observing changes from a remote NFC device.
class Observer {
public:
virtual ~Observer() {}
// Called when a remote NFC device with the object |object_path| is added
// to the set of known devices.
virtual void DeviceAdded(const dbus::ObjectPath& object_path) {}
// Called when a remote NFC device with the object path |object_path| is
// removed from the set of known devices.
virtual void DeviceRemoved(const dbus::ObjectPath& object_path) {}
// Called when the device property with the name |property_name| on device
// with object path |object_path| has acquired a new value.
virtual void DevicePropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
};
~NfcDeviceClient() override;
// Adds and removes observers for events on all remote NFC devices. Check the
// |object_path| parameter of observer methods to determine which device is
// issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the list of device object paths associated with the given adapter
// identified by the D-Bus object path |adapter_path|.
virtual std::vector<dbus::ObjectPath> GetDevicesForAdapter(
const dbus::ObjectPath& adapter_path) = 0;
// Obtain the properties for the NFC device with object path |object_path|;
// any values should be copied if needed.
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
// Creates an NDEF record for the NFC device with object path |object_path|
// using the parameters in |attributes|. |attributes| is a dictionary,
// containing the NFC Record properties which will be assigned to the
// resulting record object and pushed to the device. The properties are
// defined by the NFC Record interface (see namespace "nfc_record" in
// third_party/cros_system_api/dbus/service_constants.h and
// NfcRecordClient::Properties). |attributes| should at least contain a
// "Type" plus any other properties associated with that type. For example:
//
// {
// "Type": "Text",
// "Encoding": "UTF-8",
// "Language": "en",
// "Representation": "Chrome OS rulez!"
// },
// {
// "Type": "URI",
// "URI": "http://www.chromium.org"
// },
// etc.
virtual void Push(
const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) = 0;
// Creates the instance.
static NfcDeviceClient* Create(NfcAdapterClient* adapter_client);
protected:
friend class NfcClientTest;
NfcDeviceClient();
private:
DISALLOW_COPY_AND_ASSIGN(NfcDeviceClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_DEVICE_CLIENT_H_

@ -1,181 +0,0 @@
// 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/nfc_manager_client.h"
#include <memory>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "dbus/bus.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
NfcManagerClient::Properties::Properties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: NfcPropertySet(object_proxy,
nfc_manager::kNfcManagerInterface,
callback) {
RegisterProperty(nfc_manager::kAdaptersProperty, &adapters);
}
NfcManagerClient::Properties::~Properties() {
}
// The NfcManagerClient implementation used in production.
class NfcManagerClientImpl : public NfcManagerClient {
public:
NfcManagerClientImpl()
: object_proxy_(NULL),
weak_ptr_factory_(this) {
}
~NfcManagerClientImpl() override {}
// NfcManagerClient override.
void AddObserver(Observer* observer) override {
DCHECK(observer);
observers_.AddObserver(observer);
}
// NfcManagerClient override.
void RemoveObserver(Observer* observer) override {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
// NfcManagerClient override.
Properties* GetProperties() override { return properties_.get(); }
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
VLOG(1) << "Creating NfcManagerClientImpl";
// Create the object proxy.
object_proxy_ = bus->GetObjectProxy(
nfc_manager::kNfcManagerServiceName,
dbus::ObjectPath(nfc_manager::kNfcManagerServicePath));
// Set up the signal handlers.
object_proxy_->ConnectToSignal(
nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterAddedSignal,
base::Bind(&NfcManagerClientImpl::AdapterAddedReceived,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&NfcManagerClientImpl::AdapterAddedConnected,
weak_ptr_factory_.GetWeakPtr()));
object_proxy_->ConnectToSignal(
nfc_manager::kNfcManagerInterface,
nfc_manager::kAdapterRemovedSignal,
base::Bind(&NfcManagerClientImpl::AdapterRemovedReceived,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&NfcManagerClientImpl::AdapterRemovedConnected,
weak_ptr_factory_.GetWeakPtr()));
// Create the properties structure.
properties_.reset(new Properties(
object_proxy_,
base::Bind(&NfcManagerClientImpl::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr())));
properties_->ConnectSignals();
object_proxy_->WaitForServiceToBeAvailable(
base::Bind(&NfcManagerClientImpl::OnServiceInitiallyAvailable,
weak_ptr_factory_.GetWeakPtr()));
}
private:
// Called by |object_proxy_| when the D-Bus service initially becomes
// available.
void OnServiceInitiallyAvailable(bool service_is_available) {
if (service_is_available)
properties_->GetAll();
else
LOG(ERROR) << "Failed to wait for D-Bus service to become available";
}
// NFC manager signal handlers.
void OnPropertyChanged(const std::string& property_name) {
VLOG(1) << "NFC Manager property changed: " << property_name;
FOR_EACH_OBSERVER(Observer, observers_,
ManagerPropertyChanged(property_name));
}
// Called by dbus:: when an "AdapterAdded" signal is received.
void AdapterAddedReceived(dbus::Signal* signal) {
DCHECK(signal);
dbus::MessageReader reader(signal);
dbus::ObjectPath object_path;
if (!reader.PopObjectPath(&object_path)) {
LOG(WARNING) << "AdapterAdded signal has incorrect parameters: "
<< signal->ToString();
return;
}
VLOG(1) << "Adapter added: " << object_path.value();
FOR_EACH_OBSERVER(Observer, observers_, AdapterAdded(object_path));
}
// Called by dbus:: when the "AdapterAdded" signal is initially connected.
void AdapterAddedConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
LOG_IF(WARNING, !success) << "Failed to connect to AdapterAdded signal.";
}
// Called by dbus:: when an "AdapterRemoved" signal is received..
void AdapterRemovedReceived(dbus::Signal* signal) {
DCHECK(signal);
dbus::MessageReader reader(signal);
dbus::ObjectPath object_path;
if (!reader.PopObjectPath(&object_path)) {
LOG(WARNING) << "AdapterRemoved signal has incorrect parameters: "
<< signal->ToString();
return;
}
VLOG(1) << "Adapter removed: " << object_path.value();
FOR_EACH_OBSERVER(Observer, observers_, AdapterRemoved(object_path));
}
// Called by dbus:: when the "AdapterAdded" signal is initially connected.
void AdapterRemovedConnected(const std::string& interface_name,
const std::string& signal_name,
bool success) {
LOG_IF(WARNING, !success) << "Failed to connect to AdapterRemoved signal.";
}
// D-Bus proxy for neard Manager interface.
dbus::ObjectProxy* object_proxy_;
// Properties for neard Manager interface.
std::unique_ptr<Properties> properties_;
// List of observers interested in event notifications.
base::ObserverList<NfcManagerClient::Observer> observers_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcManagerClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcManagerClientImpl);
};
NfcManagerClient::NfcManagerClient() {
}
NfcManagerClient::~NfcManagerClient() {
}
// static
NfcManagerClient* NfcManagerClient::Create() {
return new NfcManagerClientImpl();
}
} // namespace chromeos

@ -1,78 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_MANAGER_CLIENT_H_
#define CHROMEOS_DBUS_NFC_MANAGER_CLIENT_H_
#include <vector>
#include "base/macros.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
// NfcManagerClient is used to communicate with the neard Manager service.
class CHROMEOS_EXPORT NfcManagerClient : public DBusClient {
public:
// Structure of properties associated with the NFC manager.
struct Properties : public NfcPropertySet {
// List of Adapter object paths.
dbus::Property<std::vector<dbus::ObjectPath> > adapters;
Properties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~Properties() override;
};
// Interface for observing changes to the NFC manager. Use this interface
// to be notified when NFC adapters get added or removed.
// NOTE: Users of the NFC D-Bus client code shouldn't need to observe changes
// from NfcManagerClient::Observer; to get notified of changes to the list of
// NFC adapters, use NfcAdapterClient::Observer instead.
class Observer {
public:
virtual ~Observer() {}
// Called when a new adapter with object path |object_path| is added to the
// system.
virtual void AdapterAdded(const dbus::ObjectPath& object_path) {}
// Called when an adapter with object path |object_path| is removed from the
// system.
virtual void AdapterRemoved(const dbus::ObjectPath& object_path) {}
// Called when the manager property with name |property_name| has acquired
// a new value.
virtual void ManagerPropertyChanged(const std::string& property_name) {}
};
~NfcManagerClient() override;
// Adds and removes observers for events on the NFC manager.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Obtains the properties of the NFC manager service.
virtual Properties* GetProperties() = 0;
// Creates the instance.
static NfcManagerClient* Create();
protected:
friend class NfcClientTest;
NfcManagerClient();
private:
DISALLOW_COPY_AND_ASSIGN(NfcManagerClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_MANAGER_CLIENT_H_

@ -1,101 +0,0 @@
// 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/nfc_property_set.h"
#include "base/bind.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
NfcPropertySet::NfcPropertySet(dbus::ObjectProxy* object_proxy,
const std::string& interface,
const PropertyChangedCallback& callback)
: dbus::PropertySet(object_proxy, interface, callback),
weak_ptr_factory_(this) {}
NfcPropertySet::~NfcPropertySet() {
}
void NfcPropertySet::ConnectSignals() {
object_proxy()->ConnectToSignal(
interface(), nfc_common::kPropertyChangedSignal,
base::Bind(&dbus::PropertySet::ChangedReceived,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&dbus::PropertySet::ChangedConnected,
weak_ptr_factory_.GetWeakPtr()));
}
void NfcPropertySet::SetAllPropertiesReceivedCallback(
const base::Closure& callback) {
on_get_all_callback_ = callback;
}
void NfcPropertySet::Get(dbus::PropertyBase* property,
GetCallback callback) {
NOTREACHED() << "neard does not implement Get for properties.";
}
void NfcPropertySet::GetAll() {
dbus::MethodCall method_call(
interface(), nfc_common::kGetProperties);
object_proxy()->CallMethodWithErrorCallback(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&dbus::PropertySet::OnGetAll, weak_ptr_factory_.GetWeakPtr()),
base::Bind(&NfcPropertySet::OnGetAllError,
weak_ptr_factory_.GetWeakPtr()));
}
void NfcPropertySet::OnGetAll(dbus::Response* response) {
// First invoke the superclass implementation. If the call to GetAll was
// successful, this will invoke the PropertyChangedCallback passed to the
// constructor for each individual property received through the call and
// make sure that the values of the properties have been cached. This way,
// all received properties will be available when |on_get_all_callback_| is
// run.
dbus::PropertySet::OnGetAll(response);
if (response) {
VLOG(2) << "NfcPropertySet::GetAll returned successfully.";
if (!on_get_all_callback_.is_null())
on_get_all_callback_.Run();
}
}
void NfcPropertySet::Set(dbus::PropertyBase* property,
SetCallback callback) {
dbus::MethodCall method_call(
interface(), nfc_common::kSetProperty);
dbus::MessageWriter writer(&method_call);
writer.AppendString(property->name());
property->AppendSetValueToWriter(&writer);
object_proxy()->CallMethod(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&dbus::PropertySet::OnSet, weak_ptr_factory_.GetWeakPtr(),
property, callback));
}
void NfcPropertySet::ChangedReceived(dbus::Signal* signal) {
DCHECK(signal);
dbus::MessageReader reader(signal);
UpdatePropertyFromReader(&reader);
}
void NfcPropertySet::OnGetAllError(dbus::ErrorResponse* response) {
if (response) {
dbus::MessageReader reader(response);
std::string error_message;
reader.PopString(&error_message);
if (response->GetErrorName() == DBUS_ERROR_SERVICE_UNKNOWN) {
// Do not LOG(ERROR) if service is unknown. crbug.com/393311.
VLOG(2) << "NfcPropertySet::GetAll failed because the service is unknown."
<< " NFC not enabled on this device? : " << error_message;
} else {
LOG(ERROR) << "NfcPropertySet::GetAll failed: " << error_message;
}
}
OnGetAll(nullptr);
}
} // namespace chromeos

@ -1,61 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_PROPERTY_SET_H_
#define CHROMEOS_DBUS_NFC_PROPERTY_SET_H_
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
// neard doesn't use the standard D-Bus interfaces for property access and
// instead defines property accessor methods in each D-Bus interface. This
// class customizes dbus::PropertySet to generate the correct method call to
// get all properties, connect to the correct signal and parse it correctly.
class NfcPropertySet : public dbus::PropertySet {
public:
NfcPropertySet(dbus::ObjectProxy* object_proxy,
const std::string& interface,
const PropertyChangedCallback& callback);
// Destructor; we don't hold on to any references or memory that needs
// explicit clean-up, but clang thinks we might.
~NfcPropertySet() override;
// Caches |callback| so that it will be invoked after a call to GetAll()
// has successfully received all existing properties from the remote object.
void SetAllPropertiesReceivedCallback(const base::Closure& callback);
// dbus::PropertySet overrides
void ConnectSignals() override;
void Get(dbus::PropertyBase* property, GetCallback callback) override;
void GetAll() override;
void OnGetAll(dbus::Response* response) override;
void Set(dbus::PropertyBase* property, SetCallback callback) override;
void ChangedReceived(dbus::Signal* signal) override;
protected:
const base::Closure& on_get_all_callback() { return on_get_all_callback_; }
private:
void OnGetAllError(dbus::ErrorResponse* response);
// Optional callback used to notify clients when all properties were received
// after a call to GetAll.
base::Closure on_get_all_callback_;
base::WeakPtrFactory<NfcPropertySet> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcPropertySet);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_PROPERTY_SET_H_

@ -1,279 +0,0 @@
// 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/nfc_record_client.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/bus.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using chromeos::nfc_client_helpers::DBusObjectMap;
using chromeos::nfc_client_helpers::ObjectProxyTree;
namespace chromeos {
NfcRecordClient::Properties::Properties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: NfcPropertySet(object_proxy,
nfc_record::kNfcRecordInterface,
callback) {
RegisterProperty(nfc_record::kTypeProperty, &type);
RegisterProperty(nfc_record::kLanguageProperty, &language);
RegisterProperty(nfc_record::kEncodingProperty, &encoding);
RegisterProperty(nfc_record::kRepresentationProperty, &representation);
RegisterProperty(nfc_record::kUriProperty, &uri);
RegisterProperty(nfc_record::kMimeTypeProperty, &mime_type);
RegisterProperty(nfc_record::kSizeProperty, &size);
RegisterProperty(nfc_record::kActionProperty, &action);
}
NfcRecordClient::Properties::~Properties() {
}
// The NfcRecordClient implementation used in production.
class NfcRecordClientImpl : public NfcRecordClient,
public NfcDeviceClient::Observer,
public NfcTagClient::Observer,
public DBusObjectMap::Delegate {
public:
explicit NfcRecordClientImpl(NfcDeviceClient* device_client,
NfcTagClient* tag_client)
: bus_(NULL),
device_client_(device_client),
tag_client_(tag_client),
weak_ptr_factory_(this) {
DCHECK(device_client);
DCHECK(tag_client);
}
~NfcRecordClientImpl() override {
DCHECK(device_client_);
DCHECK(tag_client_);
device_client_->RemoveObserver(this);
tag_client_->RemoveObserver(this);
}
// NfcRecordClient override.
void AddObserver(NfcRecordClient::Observer* observer) override {
DCHECK(observer);
observers_.AddObserver(observer);
}
// NfcRecordClient override.
void RemoveObserver(NfcRecordClient::Observer* observer) override {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
std::vector<dbus::ObjectPath> GetRecordsForDevice(
const dbus::ObjectPath& device_path) override {
DBusObjectMap* object_map =
devices_and_tags_to_object_maps_.GetObjectMap(device_path);
if (!object_map)
return std::vector<dbus::ObjectPath>();
return object_map->GetObjectPaths();
}
std::vector<dbus::ObjectPath> GetRecordsForTag(
const dbus::ObjectPath& tag_path) override {
return GetRecordsForDevice(tag_path);
}
// NfcRecordClient override.
Properties* GetProperties(const dbus::ObjectPath& object_path) override {
return static_cast<Properties*>(
devices_and_tags_to_object_maps_.FindObjectProperties(object_path));
}
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
VLOG(1) << "Creating NfcRecordClient impl";
DCHECK(bus);
bus_ = bus;
DCHECK(device_client_);
DCHECK(tag_client_);
device_client_->AddObserver(this);
tag_client_->AddObserver(this);
}
private:
// NfcDeviceClient::Observer override.
void DeviceAdded(const dbus::ObjectPath& object_path) override {
VLOG(1) << "Device added. Creating map for record proxies belonging to "
<< "device: " << object_path.value();
devices_and_tags_to_object_maps_.CreateObjectMap(
object_path, nfc_record::kNfcRecordServiceName, this, bus_);
}
// NfcDeviceClient::Observer override.
void DeviceRemoved(const dbus::ObjectPath& object_path) override {
// Neard doesn't send out property changed signals for the records that
// are removed when the device they belong to is removed. Clean up the
// object proxies for records that belong to the removed device.
// Note: DBusObjectMap guarantees that the Properties structure for the
// removed adapter will be valid before this method returns.
VLOG(1) << "Device removed. Cleaning up record proxies belonging to "
<< "device: " << object_path.value();
devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
}
// NfcDeviceClient::Observer override.
void DevicePropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override {
// Update the record proxies using records from the device.
DCHECK(device_client_);
NfcDeviceClient::Properties* device_properties =
device_client_->GetProperties(object_path);
// Ignore changes to properties other than "Records".
if (property_name != device_properties->records.name())
return;
// Update known records.
VLOG(1) << "NFC records changed.";
const std::vector<dbus::ObjectPath>& received_records =
device_properties->records.value();
DBusObjectMap* object_map =
devices_and_tags_to_object_maps_.GetObjectMap(object_path);
DCHECK(object_map);
object_map->UpdateObjects(received_records);
}
// NfcTagClient::Observer override.
void TagAdded(const dbus::ObjectPath& object_path) override {
VLOG(1) << "Tag added. Creating map for record proxies belonging to "
<< "tag: " << object_path.value();
devices_and_tags_to_object_maps_.CreateObjectMap(
object_path, nfc_record::kNfcRecordServiceName, this, bus_);
}
// NfcTagClient::Observer override.
void TagRemoved(const dbus::ObjectPath& object_path) override {
// Neard doesn't send out property changed signals for the records that
// are removed when the tag they belong to is removed. Clean up the
// object proxies for records that belong to the removed tag.
// Note: DBusObjectMap guarantees that the Properties structure for the
// removed adapter will be valid before this method returns.
VLOG(1) << "Tag removed. Cleaning up record proxies belonging to "
<< "tag: " << object_path.value();
devices_and_tags_to_object_maps_.RemoveObjectMap(object_path);
}
// NfcTagClient::Observer override.
void TagPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override {
// Update the record proxies using records from the tag.
DCHECK(device_client_);
NfcTagClient::Properties* tag_properties =
tag_client_->GetProperties(object_path);
// Ignore changes to properties other than "Records".
if (property_name != tag_properties->records.name())
return;
// Update known records.
VLOG(1) << "NFC records changed.";
const std::vector<dbus::ObjectPath>& received_records =
tag_properties->records.value();
DBusObjectMap* object_map =
devices_and_tags_to_object_maps_.GetObjectMap(object_path);
DCHECK(object_map);
object_map->UpdateObjects(received_records);
// When rewriting the record to a tag, neard fires a property changed
// signal for the tags "Records" property, without creating a new object
// path. Sync the properties of all records here, in case Update objects
// doesn't do it.
VLOG(1) << "Fetch properties for all records.";
object_map->RefreshAllProperties();
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
NfcPropertySet* CreateProperties(dbus::ObjectProxy* object_proxy) override {
Properties* properties = new Properties(
object_proxy,
base::Bind(&NfcRecordClientImpl::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
properties->SetAllPropertiesReceivedCallback(
base::Bind(&NfcRecordClientImpl::OnPropertiesReceived,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
return properties;
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectAdded(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordAdded(object_path));
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectRemoved(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordRemoved(object_path));
}
// Called by NfcPropertySet when a property value is changed, either by
// result of a signal or response to a GetAll() or Get() call.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {
VLOG(1) << "Record property changed; Path: " << object_path.value()
<< " Property: " << property_name;
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordPropertyChanged(object_path, property_name));
}
// Called by NfcPropertySet when all properties have been processed as a
// result of a call to GetAll.
void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
VLOG(1) << "All record properties received; Path: " << object_path.value();
FOR_EACH_OBSERVER(NfcRecordClient::Observer, observers_,
RecordPropertiesReceived(object_path));
}
// We maintain a pointer to the bus to be able to request proxies for
// new NFC records that appear.
dbus::Bus* bus_;
// List of observers interested in event notifications.
base::ObserverList<NfcRecordClient::Observer> observers_;
// Mapping from object paths to object proxies and properties structures that
// were already created by us. Record objects belong to either Tag or Device
// objects. This structure stores a different DBusObjectMap for each known
// device and tag.
ObjectProxyTree devices_and_tags_to_object_maps_;
// The device and tag clients that we listen to events notifications from.
NfcDeviceClient* device_client_;
NfcTagClient* tag_client_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcRecordClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcRecordClientImpl);
};
NfcRecordClient::NfcRecordClient() {
}
NfcRecordClient::~NfcRecordClient() {
}
NfcRecordClient* NfcRecordClient::Create(NfcDeviceClient* device_client,
NfcTagClient* tag_client) {
return new NfcRecordClientImpl(device_client, tag_client);
}
} // namespace chromeos

@ -1,146 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_RECORD_CLIENT_H_
#define CHROMEOS_DBUS_NFC_RECORD_CLIENT_H_
#include <stdint.h>
#include <string>
#include "base/macros.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
class NfcDeviceClient;
class NfcTagClient;
// NfcRecordClient is used to communicate with objects representing NDEF
// records that are stored in remote NFC tags and devices.
class CHROMEOS_EXPORT NfcRecordClient : public DBusClient {
public:
// Structure of properties associated with an NFC record.
struct Properties : public NfcPropertySet {
// The NDEF record type. Possible values are "SmartPoster", "Text", "URI",
// "HandoverRequest", "HandoverSelect", "HandoverCarrier". Read-only.
dbus::Property<std::string> type;
// The character encoding. Possible values are "UTF-8" or "UTF-16".
// This property is only valid for Text and SmartPoster's title records.
// Read-only.
dbus::Property<std::string> encoding;
// The ISO/IANA language code (For example "en" or "jp"). This property is
// only valid for Text and SmartPoster's title records.
dbus::Property<std::string> language;
// The human readable representation of a text or title record.
// This property is only valid for Text and SmartPoster's title records.
// Read-only.
dbus::Property<std::string> representation;
// The record URI (for example https://nfc-forum.org). This is the complete
// URI, including the scheme and the resource. This property is only valid
// for SmartPoster's URI type records.
// Read-only.
dbus::Property<std::string> uri;
// The URI object MIME type. This is a description of the MIME type of the
// object the URI points at. This is not a mandatory field and is only
// valid for SmartPosters carrying a URI record.
// Read-only.
dbus::Property<std::string> mime_type;
// The URI object size. This is the size of the object the URI points at.
// It should be used by applications to decide if they can afford to fetch
// the object or not. This is not a mandatory field and is only valid for
// Smart Posters carrying a URI record.
// Read-only.
dbus::Property<uint32_t> size;
// The suggested course of action. This one is only valid for Smart Posters
// and is a suggestion only. It can be ignored, and the possible values are
// "Do" (for example launch the browser), "Save" (for example save the URI
// in the bookmarks folder), or "Edit" (for example open the URI in an URI
// editor for the user to modify it).
dbus::Property<std::string> action;
Properties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~Properties() override;
};
// Interface for observing changes from a remote NFC NDEF record.
class Observer {
public:
virtual ~Observer() {}
// Called when a remote NFC record with the object path |object_path| is
// added to the set of known records.
virtual void RecordAdded(const dbus::ObjectPath& object_path) {}
// Called when a remote NFC record with the object path |object_path| is
// removed from the set of known records.
virtual void RecordRemoved(const dbus::ObjectPath& object_path) {}
// Called when the record property with the name |property_name| on record
// with object path |object_path| has acquired a new value.
virtual void RecordPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
// Called when all properties for the record with object path |object_path|
// have been received. This method will be called after
// Observer::RecordPropertyChanged has been called for all properties that
// were received through the initial property fetch that is done when the
// object proxy is first created or after a call to
// dbus::PropertySet::GetAll Observers can use this method to be notified
// when all existing properties of a record are available for use.
virtual void RecordPropertiesReceived(
const dbus::ObjectPath& object_path) {}
};
~NfcRecordClient() override;
// Adds and removes observers for events on all remote NFC records. Check the
// |object_path| parameter of observer methods to determine which record is
// issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the list of record object paths associated with the given device
// identified by the D-Bus object path |device_path|.
virtual std::vector<dbus::ObjectPath> GetRecordsForDevice(
const dbus::ObjectPath& device_path) = 0;
// Returns the list of record object paths associated with the given tag
// identified by the D-Bus object path |tag_path|.
virtual std::vector<dbus::ObjectPath> GetRecordsForTag(
const dbus::ObjectPath& tag_path) = 0;
// Obtain the properties for the NFC record with object path |object_path|;
// any values should be copied if needed.
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
// Creates the instance.
static NfcRecordClient* Create(NfcDeviceClient* device_client,
NfcTagClient* tag_client);
protected:
friend class NfcClientTest;
NfcRecordClient();
private:
DISALLOW_COPY_AND_ASSIGN(NfcRecordClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_RECORD_CLIENT_H_

@ -1,257 +0,0 @@
// 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/nfc_tag_client.h"
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/strings/stringprintf.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/values_util.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using chromeos::nfc_client_helpers::DBusObjectMap;
using chromeos::nfc_client_helpers::ObjectProxyTree;
namespace chromeos {
NfcTagClient::Properties::Properties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: NfcPropertySet(object_proxy,
nfc_tag::kNfcTagInterface,
callback) {
RegisterProperty(nfc_tag::kTypeProperty, &type);
RegisterProperty(nfc_tag::kProtocolProperty, &protocol);
RegisterProperty(nfc_tag::kRecordsProperty, &records);
RegisterProperty(nfc_tag::kReadOnlyProperty, &read_only);
}
NfcTagClient::Properties::~Properties() {
}
// The NfcTagClient implementation used in production.
class NfcTagClientImpl : public NfcTagClient,
public NfcAdapterClient::Observer,
public DBusObjectMap::Delegate {
public:
explicit NfcTagClientImpl(NfcAdapterClient* adapter_client)
: bus_(NULL),
adapter_client_(adapter_client),
weak_ptr_factory_(this) {
DCHECK(adapter_client);
}
~NfcTagClientImpl() override {
DCHECK(adapter_client_);
adapter_client_->RemoveObserver(this);
}
// NfcTagClient override.
void AddObserver(NfcTagClient::Observer* observer) override {
DCHECK(observer);
observers_.AddObserver(observer);
}
// NfcTagClient override.
void RemoveObserver(NfcTagClient::Observer* observer) override {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
// NfcTagClient override.
std::vector<dbus::ObjectPath> GetTagsForAdapter(
const dbus::ObjectPath& adapter_path) override {
DBusObjectMap* object_map =
adapters_to_object_maps_.GetObjectMap(adapter_path);
if (!object_map)
return std::vector<dbus::ObjectPath>();
return object_map->GetObjectPaths();
}
// NfcTagClient override.
Properties* GetProperties(const dbus::ObjectPath& object_path) override {
return static_cast<Properties*>(
adapters_to_object_maps_.FindObjectProperties(object_path));
}
// NfcTagClient override.
void Write(const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) override {
dbus::ObjectProxy* object_proxy =
adapters_to_object_maps_.FindObjectProxy(object_path);
if (!object_proxy) {
std::string error_message =
base::StringPrintf("NFC tag with object path \"%s\" does not exist.",
object_path.value().c_str());
LOG(ERROR) << error_message;
error_callback.Run(nfc_client_helpers::kUnknownObjectError,
error_message);
return;
}
// |attributes| should not be empty.
if (attributes.empty()) {
std::string error_message =
"Cannot write data to tag with empty arguments.";
LOG(ERROR) << error_message;
error_callback.Run(nfc_error::kInvalidArguments, error_message);
return;
}
// Create the arguments.
dbus::MethodCall method_call(nfc_tag::kNfcTagInterface, nfc_tag::kWrite);
dbus::MessageWriter writer(&method_call);
dbus::AppendValueData(&writer, attributes);
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&nfc_client_helpers::OnSuccess, callback),
base::Bind(&nfc_client_helpers::OnError, error_callback));
}
protected:
// DBusClient override.
void Init(dbus::Bus* bus) override {
VLOG(1) << "Creating NfcTagClientImpl";
DCHECK(bus);
bus_ = bus;
DCHECK(adapter_client_);
adapter_client_->AddObserver(this);
}
private:
// NfcAdapterClient::Observer override.
void AdapterAdded(const dbus::ObjectPath& object_path) override {
VLOG(1) << "Adapter added. Creating map for tag proxies belonging to "
<< "adapter: " << object_path.value();
adapters_to_object_maps_.CreateObjectMap(
object_path, nfc_tag::kNfcTagServiceName, this, bus_);
}
// NfcAdapterClient::Observer override.
void AdapterRemoved(const dbus::ObjectPath& object_path) override {
// Neard doesn't send out property changed signals for the tags that
// are removed when the adapter they belong to is removed. Clean up the
// object proxies for devices that are managed by the removed adapter.
// Note: DBusObjectMap guarantees that the Properties structure for the
// removed adapter will be valid before this method returns.
VLOG(1) << "Adapter removed. Cleaning up tag proxies belonging to "
<< "adapter: " << object_path.value();
adapters_to_object_maps_.RemoveObjectMap(object_path);
}
// NfcAdapterClient::Observer override.
void AdapterPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override {
// Update the tag proxies.
DCHECK(adapter_client_);
NfcAdapterClient::Properties *adapter_properties =
adapter_client_->GetProperties(object_path);
DCHECK(adapter_properties);
if (!adapter_properties) {
LOG(ERROR) << "No property structure found for adapter: "
<< object_path.value();
return;
}
// Ignore changes to properties other than "Tags".
if (property_name != adapter_properties->tags.name())
return;
// Update the known tags.
VLOG(1) << "NFC tags changed.";
const std::vector<dbus::ObjectPath>& received_tags =
adapter_properties->tags.value();
DBusObjectMap* object_map =
adapters_to_object_maps_.GetObjectMap(object_path);
DCHECK(object_map);
object_map->UpdateObjects(received_tags);
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
NfcPropertySet* CreateProperties(dbus::ObjectProxy* object_proxy) override {
Properties* properties = new Properties(
object_proxy,
base::Bind(&NfcTagClientImpl::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
properties->SetAllPropertiesReceivedCallback(
base::Bind(&NfcTagClientImpl::OnPropertiesReceived,
weak_ptr_factory_.GetWeakPtr(),
object_proxy->object_path()));
return properties;
}
// nfc_client_helpers::DBusObjectMap::Delegate override.
void ObjectAdded(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
TagAdded(object_path));
}
void ObjectRemoved(const dbus::ObjectPath& object_path) override {
FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
TagRemoved(object_path));
}
// Called by NfcPropertySet when a property value is changed, either by
// result of a signal or response to a GetAll() or Get() call.
void OnPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {
VLOG(1) << "Tag property changed; Path: " << object_path.value()
<< " Property: " << property_name;
FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
TagPropertyChanged(object_path, property_name));
}
// Called by NfcPropertySet when all properties have been processed as a
// result of a call to GetAll.
void OnPropertiesReceived(const dbus::ObjectPath& object_path) {
VLOG(1) << "All tag properties received; Path: " << object_path.value();
FOR_EACH_OBSERVER(NfcTagClient::Observer, observers_,
TagPropertiesReceived(object_path));
}
// We maintain a pointer to the bus to be able to request proxies for
// new NFC tags that appear.
dbus::Bus* bus_;
// List of observers interested in event notifications.
base::ObserverList<NfcTagClient::Observer> observers_;
// Mapping from object paths to object proxies and properties structures that
// were already created by us. This stucture stores a different DBusObjectMap
// for each known NFC adapter object path.
ObjectProxyTree adapters_to_object_maps_;
// The adapter client that we listen to events notifications from.
NfcAdapterClient* adapter_client_;
// Weak pointer factory for generating 'this' pointers that might live longer
// than we do.
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcTagClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcTagClientImpl);
};
NfcTagClient::NfcTagClient() {
}
NfcTagClient::~NfcTagClient() {
}
NfcTagClient* NfcTagClient::Create(NfcAdapterClient* adapter_client) {
return new NfcTagClientImpl(adapter_client);
}
} // namespace chromeos

@ -1,138 +0,0 @@
// 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.
#ifndef CHROMEOS_DBUS_NFC_TAG_CLIENT_H_
#define CHROMEOS_DBUS_NFC_TAG_CLIENT_H_
#include <map>
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/values.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/nfc_client_helpers.h"
#include "chromeos/dbus/nfc_property_set.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/property.h"
namespace chromeos {
class NfcAdapterClient;
// NfcTagClient is used to communicate with objects representing remote NFC
// tags.
class CHROMEOS_EXPORT NfcTagClient : public DBusClient {
public:
// Structure of properties associated with an NFC tag.
struct Properties : public NfcPropertySet {
// The NFC tag type. Possible values are "Type 1", "Type 2", "Type 3",
// and "Type 4". Read-only.
dbus::Property<std::string> type;
// The NFC tag radio protocol. Possible values are "Felica", "MIFARE",
// "Jewel", "ISO-DEP", and "NFC-DEP". Read-only.
dbus::Property<std::string> protocol;
// List of object paths for NDEF Records associated with the NFC tag.
// Read-only.
dbus::Property<std::vector<dbus::ObjectPath> > records;
// The current status of the tag's read mode. Read-only.
dbus::Property<bool> read_only;
Properties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~Properties() override;
};
// Interface for observing changes from a remote NFC tag.
class Observer {
public:
virtual ~Observer() {}
// Called when a remote NFC tag with the object path |object_path| is added
// to the set of known tags.
virtual void TagAdded(const dbus::ObjectPath& object_path) {}
// Called when a remote NFC tag with the object path |object_path| is
// removed from the set of known tags.
virtual void TagRemoved(const dbus::ObjectPath& object_path) {}
// Called when the tag property with the name |property_name| on tag with
// object path |object_path| has acquired a new value.
virtual void TagPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
// Called when all properties for the tag with object path |object_path|
// have been received. This method will be called after
// Observer::TagPropertyChanged has been called for all properties that
// were received through the initial property fetch that is done when the
// object proxy is first created or after a call to
// dbus::PropertySet::GetAll. Observers can use this method to be notified
// when all existing properties of a tag are available for use.
virtual void TagPropertiesReceived(const dbus::ObjectPath& object_path) {}
};
~NfcTagClient() override;
// Adds and removes observers for events on all remote NFC tags. Check the
// |object_path| parameter of observer methods to determine which tag is
// issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the list of tag object paths associated with the given adapter
// identified by the D-Bus object path |adapter_path|.
virtual std::vector<dbus::ObjectPath> GetTagsForAdapter(
const dbus::ObjectPath& adapter_path) = 0;
// Obtain the properties for the NFC tag with object path |object_path|; any
// values should be copied if needed.
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
// Creates an NDEF record for the NFC tag with object path |object_path|
// using the parameters in |attributes|. |attributes| is a dictionary,
// containing the NFC Record properties which will be assigned to the
// resulting record object and written to the tag. The properties are defined
// by the NFC Record interface (see namespace "nfc_record" in
// third_party/cros_system_api/dbus/service_constants.h and
// NfcRecordClient::Properties). |attributes| should at least contain a
// "Type" plus any other properties associated with that type. For example:
//
// {
// "Type": "Text",
// "Encoding": "UTF-8",
// "Language": "en",
// "Representation": "Chrome OS rulez!"
// },
// {
// "Type": "URI",
// "URI": "http://www.chromium.org"
// },
// etc.
virtual void Write(
const dbus::ObjectPath& object_path,
const base::DictionaryValue& attributes,
const base::Closure& callback,
const nfc_client_helpers::ErrorCallback& error_callback) = 0;
// Creates the instance.
static NfcTagClient* Create(NfcAdapterClient* adapter_client);
protected:
friend class NfcClientTest;
NfcTagClient();
private:
DISALLOW_COPY_AND_ASSIGN(NfcTagClient);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_NFC_TAG_CLIENT_H_

@ -60,8 +60,6 @@ test("device_unittests") {
"bluetooth/test/test_bluetooth_local_gatt_service_delegate.cc",
"bluetooth/test/test_bluetooth_local_gatt_service_delegate.h",
"gamepad/gamepad_provider_unittest.cc",
"nfc/nfc_chromeos_unittest.cc",
"nfc/nfc_ndef_record_unittest.cc",
"test/run_all_unittests.cc",
]
@ -74,7 +72,6 @@ test("device_unittests") {
"//device/gamepad",
"//device/gamepad:test_helpers",
"//device/geolocation:unittests",
"//device/nfc",
"//device/power_save_blocker",
"//mojo/common",
"//mojo/edk/system",

@ -5,45 +5,6 @@
import("//build/config/features.gni")
import("//mojo/public/tools/bindings/mojom.gni")
static_library("nfc") {
sources = [
"nfc_adapter.cc",
"nfc_adapter.h",
"nfc_adapter_chromeos.cc",
"nfc_adapter_chromeos.h",
"nfc_adapter_factory.cc",
"nfc_adapter_factory.h",
"nfc_ndef_record.cc",
"nfc_ndef_record.h",
"nfc_ndef_record_utils_chromeos.cc",
"nfc_ndef_record_utils_chromeos.h",
"nfc_peer.cc",
"nfc_peer.h",
"nfc_peer_chromeos.cc",
"nfc_peer_chromeos.h",
"nfc_tag.cc",
"nfc_tag.h",
"nfc_tag_chromeos.cc",
"nfc_tag_chromeos.h",
"nfc_tag_technology.cc",
"nfc_tag_technology.h",
"nfc_tag_technology_chromeos.cc",
"nfc_tag_technology_chromeos.h",
]
deps = [
"//base",
"//url",
]
if (is_chromeos) {
deps += [
"//chromeos",
"//dbus",
]
}
}
mojom("mojo_bindings") {
sources = [
"nfc.mojom",

@ -1,5 +0,0 @@
include_rules = [
"+chromeos/dbus",
"+dbus",
"+third_party/cros_system_api/dbus",
]

@ -9,49 +9,6 @@
'../../third_party/android_tools/android_tools.gyp:android_support_v13_javalib',
},
'targets': [
{
# GN version: //device/nfc
'target_name': 'device_nfc',
'type': 'static_library',
'dependencies': [
'../../base/base.gyp:base',
'../../url/url.gyp:url_lib',
],
'sources': [
# Note: file list duplicated in GN build.
'nfc_adapter.cc',
'nfc_adapter.h',
'nfc_adapter_chromeos.cc',
'nfc_adapter_chromeos.h',
'nfc_adapter_factory.cc',
'nfc_adapter_factory.h',
'nfc_ndef_record.cc',
'nfc_ndef_record.h',
'nfc_ndef_record_utils_chromeos.cc',
'nfc_ndef_record_utils_chromeos.h',
'nfc_peer.cc',
'nfc_peer.h',
'nfc_peer_chromeos.cc',
'nfc_peer_chromeos.h',
'nfc_tag.cc',
'nfc_tag.h',
'nfc_tag_chromeos.cc',
'nfc_tag_chromeos.h',
'nfc_tag_technology.cc',
'nfc_tag_technology.h',
'nfc_tag_technology_chromeos.cc',
'nfc_tag_technology_chromeos.h'
],
'conditions': [
['chromeos==1', {
'dependencies': [
'../../build/linux/system.gyp:dbus',
'../../chromeos/chromeos.gyp:chromeos',
'../../dbus/dbus.gyp:dbus',
]
}],
],
},
{
'target_name': 'device_nfc_mojo_bindings',
'type': 'static_library',

@ -1,97 +0,0 @@
// 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 "device/nfc/nfc_adapter.h"
#include "base/stl_util.h"
#include "device/nfc/nfc_peer.h"
#include "device/nfc/nfc_tag.h"
namespace device {
NfcAdapter::NfcAdapter() {
}
NfcAdapter::~NfcAdapter() {
base::STLDeleteValues(&peers_);
base::STLDeleteValues(&tags_);
}
void NfcAdapter::GetPeers(PeerList* peer_list) const {
peer_list->clear();
for (PeersMap::const_iterator iter = peers_.begin();
iter != peers_.end(); ++iter) {
peer_list->push_back(iter->second);
}
}
void NfcAdapter::GetTags(TagList* tag_list) const {
tag_list->clear();
for (TagsMap::const_iterator iter = tags_.begin();
iter != tags_.end(); ++iter) {
tag_list->push_back(iter->second);
}
}
NfcPeer* NfcAdapter::GetPeer(const std::string& identifier) const {
PeersMap::const_iterator iter = peers_.find(identifier);
if (iter != peers_.end())
return iter->second;
return NULL;
}
NfcTag* NfcAdapter::GetTag(const std::string& identifier) const {
TagsMap::const_iterator iter = tags_.find(identifier);
if (iter != tags_.end())
return iter->second;
return NULL;
}
void NfcAdapter::SetTag(const std::string& identifier, NfcTag* tag) {
if (GetTag(identifier)) {
VLOG(1) << "Tag object for tag \"" << identifier << "\" already exists.";
return;
}
tags_[identifier] = tag;
}
void NfcAdapter::SetPeer(const std::string& identifier, NfcPeer* peer) {
if (GetPeer(identifier)) {
VLOG(1) << "Peer object for peer \"" << identifier << "\" already exists.";
return;
}
peers_[identifier] = peer;
}
NfcTag* NfcAdapter::RemoveTag(const std::string& identifier) {
TagsMap::iterator iter = tags_.find(identifier);
if (iter == tags_.end()) {
VLOG(1) << "Tag with identifier \"" << identifier << "\" not found.";
return NULL;
}
NfcTag* tag = iter->second;
tags_.erase(iter);
return tag;
}
NfcPeer* NfcAdapter::RemovePeer(const std::string& identifier) {
PeersMap::iterator iter = peers_.find(identifier);
if (iter == peers_.end()) {
VLOG(1) << "Peer object for peer \"" << identifier << "\" not found.";
return NULL;
}
NfcPeer* peer = iter->second;
peers_.erase(iter);
return peer;
}
void NfcAdapter::ClearTags() {
tags_.clear();
}
void NfcAdapter::ClearPeers() {
peers_.clear();
}
} // namespace device

@ -1,211 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_ADAPTER_H_
#define DEVICE_NFC_NFC_ADAPTER_H_
#include <map>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
namespace device {
class NfcPeer;
class NfcTag;
// NfcAdapter represents a local NFC adapter which may be used to interact with
// NFC tags and remote NFC adapters on platforms that support NFC. Through
// instances of this class, users can obtain important information such as if
// and/or when an adapter is present, supported NFC technologies, and the
// adapter's power and polling state. NfcAdapter instances can be used to power
// up/down the NFC adapter and its Observer interface allows users to get
// notified when new adapters are added/removed and when remote NFC tags and
// devices were detected or lost.
//
// A system can contain more than one NFC adapter (e.g. external USB adapters)
// but Chrome will have only one NfcAdapter instance. This instance will do
// its best to represent all underlying adapters but will only allow
// interacting with only one at a given time. If the currently represented
// adapter is removed from the system, the NfcAdapter instance will update to
// reflect the information from the next available adapter.
class NfcAdapter : public base::RefCounted<NfcAdapter> {
public:
// Interface for observing changes from NFC adapters.
class Observer {
public:
virtual ~Observer() {}
// Called when the presence of the adapter |adapter| changes. When |present|
// is true, this indicates that the adapter has now become present, while a
// value of false indicates that the adapter is no longer available on the
// current system.
virtual void AdapterPresentChanged(NfcAdapter* adapter, bool present) {}
// Called when the radio power state of the adapter |adapter| changes. If
// |powered| is true, the adapter radio is turned on, otherwise it's turned
// off.
virtual void AdapterPoweredChanged(NfcAdapter* adapter, bool powered) {}
// Called when the "polling" state of the adapter |adapter| changes. If
// |polling| is true, the adapter is currently polling for remote tags and
// devices. If false, the adapter isn't polling, either because a poll loop
// was never started or because a connection with a tag or peer has been
// established.
virtual void AdapterPollingChanged(NfcAdapter* adapter, bool polling) {}
// Called when an NFC tag |tag| has been found by the adapter |adapter|.
// The observer can use this method to take further action on the tag object
// |tag|, such as reading its records or writing to it. While |tag| will be
// valid within the context of this call, its life-time cannot be guaranteed
// once this call returns, as the object may get destroyed if the connection
// with the tag is lost. Instead of caching the pointer directly, observers
// should store the tag's assigned unique identifier instead, which can be
// used to obtain a pointer to the tag, as long as it exists.
virtual void TagFound(NfcAdapter* adapter, NfcTag* tag) {}
// Called when the NFC tag |tag| is no longer known by the adapter
// |adapter|. |tag| should not be cached.
virtual void TagLost(NfcAdapter* adapter, NfcTag* tag) {}
// Called when a remote NFC adapter |peer| has been detected, which is
// available for peer-to-peer communication over NFC. The observer can use
// this method to take further action on |peer| such as reading its records
// or pushing NDEFs to it. While |peer| will be valid within the context of
// this call, its life-time cannot be guaranteed once this call returns, as
// the object may get destroyed if the connection with the peer is lost.
// Instead of caching the pointer directly, observers should store the
// peer's assigned unique identifier instead, which can be used to obtain a
// pointer to the peer, as long as it exists.
virtual void PeerFound(NfcAdapter* adaper, NfcPeer* peer) {}
// Called when the remote NFC adapter |peer| is no longer known by the
// adapter |adapter|. |peer| should not be cached.
virtual void PeerLost(NfcAdapter* adapter, NfcPeer* peer) {}
};
// The ErrorCallback is used by methods to asynchronously report errors.
typedef base::Closure ErrorCallback;
// Typedefs for lists of NFC peer and NFC tag objects.
typedef std::vector<NfcPeer*> PeerList;
typedef std::vector<NfcTag*> TagList;
// Adds and removes observers for events on this NFC adapter. If monitoring
// multiple adapters, check the |adapter| parameter of observer methods to
// determine which adapter is issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Indicates whether an underlying adapter is actually present on the
// system. An adapter that was previously present can become no longer
// present, for example, if all physical adapters that can back it up were
// removed from the system.
virtual bool IsPresent() const = 0;
// Indicates whether the adapter radio is powered.
virtual bool IsPowered() const = 0;
// Indicates whether the adapter is polling for remote NFC tags and peers.
virtual bool IsPolling() const = 0;
// Indicates whether the NfcAdapter instance is initialized and ready to use.
virtual bool IsInitialized() const = 0;
// Requests a change to the adapter radio power. Setting |powered| to true
// will turn on the radio and false will turn it off. On success, |callback|
// will be invoked. On failure, |error_callback| will be invoked, which can
// happen if the radio power is already in the requested state, or if the
// underlying adapter is not present.
virtual void SetPowered(bool powered,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Requests the adapter to begin its poll loop to start looking for remote
// NFC tags and peers. On success, |callback| will be invoked. On failure,
// |error_callback| will be invoked. This method can fail for various
// reasons, including:
// - The adapter radio is not powered.
// - The adapter is already polling.
// - The adapter is busy; it has already established a connection to a
// remote tag or peer.
// Bear in mind that this method may be called by multiple users of the same
// adapter.
virtual void StartPolling(const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Requests the adapter to stop its current poll loop. On success, |callback|
// will be invoked. On failure, |error_callback| will be invoked. This method
// can fail if the adapter is not polling when this method was called. Bear
// in mind that this method may be called by multiple users of the same
// adapter and polling may not actually stop if other callers have called
// StartPolling() in the mean time.
virtual void StopPolling(const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Returns a list containing all known peers in |peer_list|. If |peer_list|
// was non-empty at the time of the call, it will be cleared. The contents of
// |peer_list| at the end of this call are owned by the adapter.
virtual void GetPeers(PeerList* peer_list) const;
// Returns a list containing all known tags in |tag_list|. If |tag_list| was
// non-empty at the time of the call, it will be cleared. The contents of
// |tag_list| at the end of this call are owned by the adapter.
virtual void GetTags(TagList* tag_list) const;
// Returns a pointer to the peer with the given identifier |identifier| or
// NULL if no such peer is known. If a non-NULL pointer is returned, the
// instance that it points to is owned by this adapter.
virtual NfcPeer* GetPeer(const std::string& identifier) const;
// Returns a pointer to the tag with the given identifier |identifier| or
// NULL if no such tag is known. If a non-NULL pointer is returned, the
// instance that it points to is owned by this adapter.
virtual NfcTag* GetTag(const std::string& identifier) const;
protected:
friend class base::RefCounted<NfcAdapter>;
// The default constructor does nothing. The destructor deletes all known
// NfcPeer and NfcTag instances.
NfcAdapter();
virtual ~NfcAdapter();
// Peers and tags that have been found. The key is the unique identifier
// assigned to the peer or tag and the value is a pointer to the
// corresponding NfcPeer or NfcTag object, whose lifetime is managed by the
// adapter instance.
typedef std::map<const std::string, NfcPeer*> PeersMap;
typedef std::map<const std::string, NfcTag*> TagsMap;
// Set the given tag or peer for |identifier|. If a tag or peer for
// |identifier| already exists, these methods won't do anything.
void SetTag(const std::string& identifier, NfcTag* tag);
void SetPeer(const std::string& identifier, NfcPeer* peer);
// Removes the tag or peer for |identifier| and returns the removed object.
// Returns NULL, if no tag or peer for |identifier| was found.
NfcTag* RemoveTag(const std::string& identifier);
NfcPeer* RemovePeer(const std::string& identifier);
// Clear the peer and tag maps. These methods won't delete the tag and peer
// objects, however after the call to these methods, the peers and tags won't
// be returned via calls to GetPeers and GetTags.
void ClearTags();
void ClearPeers();
private:
// Peers and tags that are managed by this adapter.
PeersMap peers_;
TagsMap tags_;
DISALLOW_COPY_AND_ASSIGN(NfcAdapter);
};
} // namespace device
#endif // DEVICE_NFC_NFC_ADAPTER_H_

@ -1,396 +0,0 @@
// 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 "device/nfc/nfc_adapter_chromeos.h"
#include <vector>
#include "base/callback.h"
#include "base/logging.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "device/nfc/nfc_peer_chromeos.h"
#include "device/nfc/nfc_tag_chromeos.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
namespace {
typedef std::vector<dbus::ObjectPath> ObjectPathVector;
} // namespace
NfcAdapterChromeOS::NfcAdapterChromeOS()
: weak_ptr_factory_(this) {
DBusThreadManager::Get()->GetNfcAdapterClient()->AddObserver(this);
DBusThreadManager::Get()->GetNfcDeviceClient()->AddObserver(this);
DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this);
const ObjectPathVector& object_paths =
DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
if (!object_paths.empty()) {
VLOG(1) << object_paths.size() << " NFC adapter(s) available.";
SetAdapter(object_paths[0]);
}
}
NfcAdapterChromeOS::~NfcAdapterChromeOS() {
DBusThreadManager::Get()->GetNfcAdapterClient()->RemoveObserver(this);
DBusThreadManager::Get()->GetNfcDeviceClient()->RemoveObserver(this);
DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
}
void NfcAdapterChromeOS::AddObserver(NfcAdapter::Observer* observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void NfcAdapterChromeOS::RemoveObserver(NfcAdapter::Observer* observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
bool NfcAdapterChromeOS::IsPresent() const {
return !object_path_.value().empty();
}
bool NfcAdapterChromeOS::IsPowered() const {
if (!IsPresent())
return false;
return DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_)->powered.value();
}
bool NfcAdapterChromeOS::IsPolling() const {
if (!IsPresent())
return false;
return DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_)->polling.value();
}
bool NfcAdapterChromeOS::IsInitialized() const {
return true;
}
void NfcAdapterChromeOS::SetPowered(bool powered,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (!IsPresent()) {
LOG(WARNING) << "Adapter not present. Cannot power up the antenna.";
error_callback.Run();
return;
}
DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_)->powered.Set(
powered,
base::Bind(&NfcAdapterChromeOS::OnSetPowered,
weak_ptr_factory_.GetWeakPtr(),
callback,
error_callback));
}
void NfcAdapterChromeOS::StartPolling(const base::Closure& callback,
const ErrorCallback& error_callback) {
// Always poll in "Initiator" mode.
DBusThreadManager::Get()->GetNfcAdapterClient()->
StartPollLoop(object_path_,
nfc_adapter::kModeInitiator,
base::Bind(&NfcAdapterChromeOS::OnStartPolling,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&NfcAdapterChromeOS::OnStartPollingError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}
void NfcAdapterChromeOS::StopPolling(const base::Closure& callback,
const ErrorCallback& error_callback) {
DBusThreadManager::Get()->GetNfcAdapterClient()->
StopPollLoop(object_path_,
base::Bind(&NfcAdapterChromeOS::OnStopPolling,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&NfcAdapterChromeOS::OnStopPollingError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}
void NfcAdapterChromeOS::AdapterAdded(const dbus::ObjectPath& object_path) {
// Set the adapter to the newly added adapter only if no adapter is present.
if (!IsPresent())
SetAdapter(object_path);
}
void NfcAdapterChromeOS::AdapterRemoved(const dbus::ObjectPath& object_path) {
if (object_path != object_path_)
return;
// The current adapter was removed, so mark us as not present and clean up
// peers and tags.
RemoveAdapter();
// There may still be other adapters present on the system. Set the next
// available adapter as the current one.
const ObjectPathVector& object_paths =
DBusThreadManager::Get()->GetNfcAdapterClient()->GetAdapters();
for (ObjectPathVector::const_iterator iter =
object_paths.begin();
iter != object_paths.end(); ++iter) {
// The removed object will still be available until the call to
// AdapterRemoved returns. Make sure that we are not re-adding the
// removed adapter.
if (*iter == object_path)
continue;
SetAdapter(*iter);
}
}
void NfcAdapterChromeOS::AdapterPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
if (object_path != object_path_)
return;
NfcAdapterClient::Properties* properties =
DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_);
if (property_name == properties->powered.name())
PoweredChanged(properties->powered.value());
else if (property_name == properties->polling.name())
PollingChanged(properties->polling.value());
}
void NfcAdapterChromeOS::DeviceAdded(const dbus::ObjectPath& object_path) {
if (!IsPresent())
return;
if (GetPeer(object_path.value()))
return;
VLOG(1) << "NFC device found: " << object_path.value();
// Check to see if the device belongs to this adapter.
const ObjectPathVector& devices =
DBusThreadManager::Get()->GetNfcDeviceClient()->
GetDevicesForAdapter(object_path_);
bool device_found = false;
for (ObjectPathVector::const_iterator iter = devices.begin();
iter != devices.end(); ++iter) {
if (*iter == object_path) {
device_found = true;
break;
}
}
if (!device_found) {
VLOG(1) << "Found peer device does not belong to the current adapter.";
return;
}
// Create the peer object.
NfcPeerChromeOS* peer_chromeos = new NfcPeerChromeOS(object_path);
SetPeer(object_path.value(), peer_chromeos);
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
PeerFound(this, peer_chromeos));
}
void NfcAdapterChromeOS::DeviceRemoved(const dbus::ObjectPath& object_path) {
VLOG(1) << "NFC device lost: " << object_path.value();
device::NfcPeer* peer = RemovePeer(object_path.value());
if (!peer) {
VLOG(1) << "Removed peer device does not belong to the current adapter.";
return;
}
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_, PeerLost(this, peer));
delete peer;
}
void NfcAdapterChromeOS::TagAdded(const dbus::ObjectPath& object_path) {
if (!IsPresent())
return;
if (GetTag(object_path.value()))
return;
VLOG(1) << "NFC tag found: " << object_path.value();
// Check to see if the tag belongs to this adapter.
const std::vector<dbus::ObjectPath>& tags =
DBusThreadManager::Get()->GetNfcTagClient()->
GetTagsForAdapter(object_path_);
bool tag_found = false;
for (std::vector<dbus::ObjectPath>::const_iterator iter = tags.begin();
iter != tags.end(); ++iter) {
if (*iter == object_path) {
tag_found = true;
break;
}
}
if (!tag_found) {
VLOG(1) << "Found tag does not belong to the current adapter.";
return;
}
// Create the tag object.
NfcTagChromeOS* tag_chromeos = new NfcTagChromeOS(object_path);
SetTag(object_path.value(), tag_chromeos);
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
TagFound(this, tag_chromeos));
}
void NfcAdapterChromeOS::TagRemoved(const dbus::ObjectPath& object_path) {
VLOG(1) << "NFC tag lost : " << object_path.value();
device::NfcTag* tag = RemoveTag(object_path.value());
if (!tag) {
VLOG(1) << "Removed tag does not belong to the current adapter.";
return;
}
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_, TagLost(this, tag));
delete tag;
}
void NfcAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) {
DCHECK(!IsPresent());
object_path_ = object_path;
VLOG(1) << "Using NFC adapter: " << object_path.value();
NfcAdapterClient::Properties* properties =
DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_);
PresentChanged(true);
if (properties->powered.value())
PoweredChanged(true);
if (properties->polling.value())
PollingChanged(true);
// Create peer objects for peers that were added before the adapter was set.
const ObjectPathVector& devices =
DBusThreadManager::Get()->GetNfcDeviceClient()->
GetDevicesForAdapter(object_path_);
for (ObjectPathVector::const_iterator iter = devices.begin();
iter != devices.end(); ++iter) {
const dbus::ObjectPath& object_path = *iter;
if (GetPeer(object_path.value()))
continue;
NfcPeerChromeOS* peer_chromeos = new NfcPeerChromeOS(object_path);
SetPeer(object_path.value(), peer_chromeos);
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
PeerFound(this, peer_chromeos));
}
// Create tag objects for tags that were added before the adapter was set.
const std::vector<dbus::ObjectPath>& tags =
DBusThreadManager::Get()->GetNfcTagClient()->
GetTagsForAdapter(object_path_);
for (std::vector<dbus::ObjectPath>::const_iterator iter = tags.begin();
iter != tags.end(); ++iter) {
const dbus::ObjectPath& object_path = *iter;
if (GetTag(object_path.value()))
continue;
NfcTagChromeOS* tag_chromeos = new NfcTagChromeOS(object_path);
SetTag(object_path.value(), tag_chromeos);
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
TagFound(this, tag_chromeos));
}
}
void NfcAdapterChromeOS::RemoveAdapter() {
DCHECK(IsPresent());
VLOG(1) << "NFC adapter removed: " << object_path_.value();
NfcAdapterClient::Properties* properties =
DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_);
if (properties->powered.value())
PoweredChanged(false);
if (properties->polling.value())
PollingChanged(false);
// Copy the tags and peers here and clear the original containers so that
// GetPeers and GetTags return no values during the *Removed observer calls.
PeerList peers;
TagList tags;
GetPeers(&peers);
GetTags(&tags);
ClearPeers();
ClearTags();
for (PeerList::iterator iter = peers.begin();
iter != peers.end(); ++iter) {
device::NfcPeer* peer = *iter;
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
PeerLost(this, peer));
delete peer;
}
for (TagList::iterator iter = tags.begin();
iter != tags.end(); ++iter) {
device::NfcTag* tag = *iter;
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
TagLost(this, tag));
delete tag;
}
object_path_ = dbus::ObjectPath("");
PresentChanged(false);
}
void NfcAdapterChromeOS::PoweredChanged(bool powered) {
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
AdapterPoweredChanged(this, powered));
}
void NfcAdapterChromeOS::PollingChanged(bool polling) {
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
AdapterPollingChanged(this, polling));
}
void NfcAdapterChromeOS::PresentChanged(bool present) {
FOR_EACH_OBSERVER(NfcAdapter::Observer, observers_,
AdapterPresentChanged(this, present));
}
void NfcAdapterChromeOS::OnSetPowered(const base::Closure& callback,
const ErrorCallback& error_callback,
bool success) {
VLOG(1) << "NfcAdapterChromeOS::OnSetPowered result: " << success;
if (success) {
// TODO(armansito): There is a bug in neard 0.13 that causes it not to emit
// a signal when the "Powered" property changes. Sync the properties here,
// but remove it in neard 0.14.
if (IsPresent()) {
DBusThreadManager::Get()->GetNfcAdapterClient()->
GetProperties(object_path_)->GetAll();
}
callback.Run();
} else {
LOG(ERROR) << "Failed to power up the NFC antenna radio.";
error_callback.Run();
}
}
void NfcAdapterChromeOS::OnStartPolling(const base::Closure& callback) {
callback.Run();
}
void NfcAdapterChromeOS::OnStartPollingError(
const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(ERROR) << object_path_.value() << ": Failed to start polling: "
<< error_name << ": " << error_message;
error_callback.Run();
}
void NfcAdapterChromeOS::OnStopPolling(const base::Closure& callback) {
callback.Run();
}
void NfcAdapterChromeOS::OnStopPollingError(
const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(ERROR) << object_path_.value() << ": Failed to stop polling: "
<< error_name << ": " << error_message;
error_callback.Run();
}
} // namespace chromeos

@ -1,113 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_
#define DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_adapter_client.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/object_path.h"
#include "device/nfc/nfc_adapter.h"
namespace device {
class NfcAdapterFactory;
} // namespace device
namespace chromeos {
// The NfcAdapterChromeOS class implements NfcAdapter for the Chrome OS
// platform.
class NfcAdapterChromeOS : public device::NfcAdapter,
public chromeos::NfcAdapterClient::Observer,
public chromeos::NfcDeviceClient::Observer,
public chromeos::NfcTagClient::Observer {
public:
// NfcAdapter overrides.
void AddObserver(NfcAdapter::Observer* observer) override;
void RemoveObserver(NfcAdapter::Observer* observer) override;
bool IsPresent() const override;
bool IsPowered() const override;
bool IsPolling() const override;
bool IsInitialized() const override;
void SetPowered(bool powered,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void StartPolling(const base::Closure& callback,
const ErrorCallback& error_callback) override;
void StopPolling(const base::Closure& callback,
const ErrorCallback& error_callback) override;
private:
friend class device::NfcAdapterFactory;
friend class NfcChromeOSTest;
NfcAdapterChromeOS();
~NfcAdapterChromeOS() override;
// NfcAdapterClient::Observer overrides.
void AdapterAdded(const dbus::ObjectPath& object_path) override;
void AdapterRemoved(const dbus::ObjectPath& object_path) override;
void AdapterPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override;
// NfcDeviceClient::Observer overrides.
void DeviceAdded(const dbus::ObjectPath& object_path) override;
void DeviceRemoved(const dbus::ObjectPath& object_path) override;
// NfcTagClient::Observer overrides.
void TagAdded(const dbus::ObjectPath& object_path) override;
void TagRemoved(const dbus::ObjectPath& object_path) override;
// Set the tracked adapter to the one in |object_path|, this object will
// subsequently operate on that adapter until it is removed.
void SetAdapter(const dbus::ObjectPath& object_path);
// Remove the currently tracked adapter. IsPresent() will return false after
// this is called.
void RemoveAdapter();
// Announce to observers a change in the adapter state.
void PoweredChanged(bool powered);
void PollingChanged(bool polling);
void PresentChanged(bool present);
// Called by dbus:: on completion of the powered property change.
void OnSetPowered(const base::Closure& callback,
const ErrorCallback& error_callback,
bool success);
// Called by dbus:: on completion of the D-Bus method call to start polling.
void OnStartPolling(const base::Closure& callback);
void OnStartPollingError(const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Called by dbus:: on completion of the D-Bus method call to stop polling.
void OnStopPolling(const base::Closure& callback);
void OnStopPollingError(const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Object path of the adapter that we are currently tracking.
dbus::ObjectPath object_path_;
// List of observers interested in event notifications from us.
base::ObserverList<device::NfcAdapter::Observer> observers_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcAdapterChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcAdapterChromeOS);
};
} // namespace chromeos
#endif // DEVICE_NFC_NFC_ADAPTER_CHROMEOS_H_

@ -1,55 +0,0 @@
// 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 "device/nfc/nfc_adapter_factory.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#if defined(OS_CHROMEOS)
#include "device/nfc/nfc_adapter_chromeos.h"
#endif
namespace device {
namespace {
// Shared default adapter instance, we don't want to keep this class around
// if nobody is using it so use a WeakPtr and create the object when needed;
// since Google C++ Style (and clang's static analyzer) forbids us having
// exit-time destructors we use a leaky lazy instance for it.
base::LazyInstance<base::WeakPtr<device::NfcAdapter> >::Leaky
default_adapter = LAZY_INSTANCE_INITIALIZER;
} // namespace
// static
bool NfcAdapterFactory::IsNfcAvailable() {
#if defined(OS_CHROMEOS)
return true;
#else
return false;
#endif
}
// static
void NfcAdapterFactory::GetAdapter(const AdapterCallback& callback) {
if (!IsNfcAvailable()) {
LOG(WARNING) << "NFC is not available on the current platform.";
return;
}
if (!default_adapter.Get().get()) {
#if defined(OS_CHROMEOS)
chromeos::NfcAdapterChromeOS* new_adapter =
new chromeos::NfcAdapterChromeOS();
default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr();
#endif
}
if (default_adapter.Get()->IsInitialized())
callback.Run(scoped_refptr<NfcAdapter>(default_adapter.Get().get()));
}
} // namespace device

@ -1,33 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_ADAPTER_FACTORY_H_
#define DEVICE_NFC_NFC_ADAPTER_FACTORY_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "device/nfc/nfc_adapter.h"
namespace device {
// NfcAdapterFactory is a class that contains static methods, which
// instantiate either a specific NFC adapter, or the generic "default
// adapter" which may change depending on availability.
class NfcAdapterFactory {
public:
typedef base::Callback<void(scoped_refptr<NfcAdapter>)> AdapterCallback;
// Returns true if NFC is available for the current platform.
static bool IsNfcAvailable();
// Returns the shared instance of the default adapter, creating and
// initializing it if necessary. |callback| is called with the adapter
// instance passed only once the adapter is fully initialized and ready to
// use.
static void GetAdapter(const AdapterCallback& callback);
};
} // namespace device
#endif // DEVICE_NFC_NFC_ADAPTER_FACTORY_H_

@ -1,862 +0,0 @@
// 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 <stddef.h>
#include <stdint.h>
#include <memory>
#include "base/callback.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_nfc_adapter_client.h"
#include "chromeos/dbus/fake_nfc_device_client.h"
#include "chromeos/dbus/fake_nfc_record_client.h"
#include "chromeos/dbus/fake_nfc_tag_client.h"
#include "device/nfc/nfc_adapter_chromeos.h"
#include "device/nfc/nfc_ndef_record.h"
#include "device/nfc/nfc_ndef_record_utils_chromeos.h"
#include "device/nfc/nfc_peer.h"
#include "device/nfc/nfc_tag.h"
#include "device/nfc/nfc_tag_technology.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using device::NfcAdapter;
using device::NfcNdefMessage;
using device::NfcNdefRecord;
using device::NfcNdefTagTechnology;
using device::NfcPeer;
using device::NfcTag;
namespace chromeos {
namespace {
// Callback passed to property structures.
void OnPropertyChangedCallback(const std::string& property_name) {
}
// Callback passed to dbus::PropertyBase::Set.
void OnSet(bool success) {
}
class TestObserver : public NfcAdapter::Observer,
public NfcPeer::Observer,
public NfcTag::Observer,
public NfcNdefTagTechnology::Observer {
public:
TestObserver(scoped_refptr<NfcAdapter> adapter)
: present_changed_count_(0),
powered_changed_count_(0),
polling_changed_count_(0),
peer_records_received_count_(0),
tag_records_received_count_(0),
peer_count_(0),
tag_count_(0),
adapter_(adapter) {
}
~TestObserver() override {}
// NfcAdapter::Observer override.
void AdapterPresentChanged(NfcAdapter* adapter, bool present) override {
EXPECT_EQ(adapter_.get(), adapter);
present_changed_count_++;
}
// NfcAdapter::Observer override.
void AdapterPoweredChanged(NfcAdapter* adapter, bool powered) override {
EXPECT_EQ(adapter_.get(), adapter);
powered_changed_count_++;
}
// NfcAdapter::Observer override.
void AdapterPollingChanged(NfcAdapter* adapter, bool powered) override {
EXPECT_EQ(adapter_.get(), adapter);
polling_changed_count_++;
}
// NfcAdapter::Observer override.
void PeerFound(NfcAdapter* adapter, NfcPeer* peer) override {
EXPECT_EQ(adapter_.get(), adapter);
peer_count_++;
peer_identifier_ = peer->GetIdentifier();
}
// NfcAdapter::Observer override.
void PeerLost(NfcAdapter* adapter, NfcPeer* peer) override {
EXPECT_EQ(adapter_.get(), adapter);
EXPECT_EQ(peer_identifier_, peer->GetIdentifier());
peer_count_--;
peer_identifier_.clear();
}
// NfcAdapter::Observer override.
void TagFound(NfcAdapter* adapter, NfcTag* tag) override {
EXPECT_EQ(adapter_.get(), adapter);
tag_count_++;
tag_identifier_ = tag->GetIdentifier();
}
// NfcAdapter::Observer override.
void TagLost(NfcAdapter* adapter, NfcTag* tag) override {
EXPECT_EQ(adapter_.get(), adapter);
EXPECT_EQ(tag_identifier_, tag->GetIdentifier());
tag_count_--;
tag_identifier_.clear();
}
// NfcPeer::Observer override.
void RecordReceived(NfcPeer* peer, const NfcNdefRecord* record) override {
EXPECT_EQ(peer, adapter_->GetPeer(peer_identifier_));
EXPECT_EQ(peer_identifier_, peer->GetIdentifier());
peer_records_received_count_++;
}
// NfcNdefTagTechnology::Observer override.
void RecordReceived(NfcTag* tag, const NfcNdefRecord* record) override {
EXPECT_EQ(tag, adapter_->GetTag(tag_identifier_));
EXPECT_EQ(tag_identifier_, tag->GetIdentifier());
tag_records_received_count_++;
}
int present_changed_count_;
int powered_changed_count_;
int polling_changed_count_;
int peer_records_received_count_;
int tag_records_received_count_;
int peer_count_;
int tag_count_;
std::string peer_identifier_;
std::string tag_identifier_;
scoped_refptr<NfcAdapter> adapter_;
};
} // namespace
class NfcChromeOSTest : public testing::Test {
public:
void SetUp() override {
DBusThreadManager::Initialize();
fake_nfc_adapter_client_ = static_cast<FakeNfcAdapterClient*>(
DBusThreadManager::Get()->GetNfcAdapterClient());
fake_nfc_device_client_ = static_cast<FakeNfcDeviceClient*>(
DBusThreadManager::Get()->GetNfcDeviceClient());
fake_nfc_record_client_ = static_cast<FakeNfcRecordClient*>(
DBusThreadManager::Get()->GetNfcRecordClient());
fake_nfc_tag_client_ = static_cast<FakeNfcTagClient*>(
DBusThreadManager::Get()->GetNfcTagClient());
fake_nfc_adapter_client_->EnablePairingOnPoll(false);
fake_nfc_device_client_->DisableSimulationTimeout();
fake_nfc_tag_client_->DisableSimulationTimeout();
success_callback_count_ = 0;
error_callback_count_ = 0;
}
void TearDown() override {
adapter_ = NULL;
DBusThreadManager::Shutdown();
}
// Assigns a new instance of NfcAdapterChromeOS to |adapter_|.
void SetAdapter() {
adapter_ = new NfcAdapterChromeOS();
ASSERT_TRUE(adapter_.get() != NULL);
ASSERT_TRUE(adapter_->IsInitialized());
base::RunLoop().RunUntilIdle();
}
// Generic callbacks for success and error.
void SuccessCallback() {
success_callback_count_++;
}
void ErrorCallback() {
error_callback_count_++;
}
void ErrorCallbackWithParameters(const std::string& error_name,
const std::string& error_message) {
LOG(INFO) << "Error callback called: " << error_name << ", "
<< error_message;
error_callback_count_++;
}
protected:
// MessageLoop instance, used to simulate asynchronous behavior.
base::MessageLoop message_loop_;
// Fields for storing the number of times SuccessCallback and ErrorCallback
// have been called.
int success_callback_count_;
int error_callback_count_;
// The NfcAdapter instance under test.
scoped_refptr<NfcAdapter> adapter_;
// The fake D-Bus client instances used for testing.
FakeNfcAdapterClient* fake_nfc_adapter_client_;
FakeNfcDeviceClient* fake_nfc_device_client_;
FakeNfcRecordClient* fake_nfc_record_client_;
FakeNfcTagClient* fake_nfc_tag_client_;
};
// Tests that the adapter updates correctly to reflect the current "default"
// adapter, when multiple adapters appear and disappear.
TEST_F(NfcChromeOSTest, PresentChanged) {
SetAdapter();
EXPECT_TRUE(adapter_->IsPresent());
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
// Remove all adapters.
fake_nfc_adapter_client_->SetAdapterPresent(false);
EXPECT_EQ(1, observer.present_changed_count_);
EXPECT_FALSE(adapter_->IsPresent());
// Add two adapters.
fake_nfc_adapter_client_->SetAdapterPresent(true);
fake_nfc_adapter_client_->SetSecondAdapterPresent(true);
EXPECT_EQ(2, observer.present_changed_count_);
EXPECT_TRUE(adapter_->IsPresent());
// Remove the first adapter. Adapter should update to the second one.
fake_nfc_adapter_client_->SetAdapterPresent(false);
EXPECT_EQ(4, observer.present_changed_count_);
EXPECT_TRUE(adapter_->IsPresent());
fake_nfc_adapter_client_->SetSecondAdapterPresent(false);
EXPECT_EQ(5, observer.present_changed_count_);
EXPECT_FALSE(adapter_->IsPresent());
}
// Tests that the adapter correctly reflects the power state.
TEST_F(NfcChromeOSTest, SetPowered) {
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
EXPECT_FALSE(adapter_->IsPowered());
// SetPowered(false), while not powered.
adapter_->SetPowered(
false,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_EQ(0, observer.powered_changed_count_);
EXPECT_EQ(0, success_callback_count_);
EXPECT_EQ(1, error_callback_count_);
// SetPowered(true).
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(1, observer.powered_changed_count_);
EXPECT_EQ(1, success_callback_count_);
EXPECT_EQ(1, error_callback_count_);
// SetPowered(true), while powered.
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_EQ(1, observer.powered_changed_count_);
EXPECT_EQ(1, success_callback_count_);
EXPECT_EQ(2, error_callback_count_);
// SetPowered(false).
adapter_->SetPowered(
false,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_EQ(2, observer.powered_changed_count_);
EXPECT_EQ(2, success_callback_count_);
EXPECT_EQ(2, error_callback_count_);
}
// Tests that the power state updates correctly when the adapter disappears.
TEST_F(NfcChromeOSTest, PresentChangedWhilePowered) {
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_TRUE(adapter_->IsPresent());
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_TRUE(adapter_->IsPowered());
fake_nfc_adapter_client_->SetAdapterPresent(false);
EXPECT_EQ(1, observer.present_changed_count_);
EXPECT_EQ(2, observer.powered_changed_count_);
EXPECT_FALSE(adapter_->IsPowered());
EXPECT_FALSE(adapter_->IsPresent());
}
// Tests that peer and record objects are created for all peers and records
// that already exist when the adapter is created.
TEST_F(NfcChromeOSTest, PeersInitializedWhenAdapterCreated) {
// Set up the adapter client.
NfcAdapterClient::Properties* properties =
fake_nfc_adapter_client_->GetProperties(
dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0));
properties->powered.Set(true, base::Bind(&OnSet));
fake_nfc_adapter_client_->StartPollLoop(
dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
base::Unretained(this)));
EXPECT_EQ(1, success_callback_count_);
EXPECT_TRUE(properties->powered.value());
EXPECT_TRUE(properties->polling.value());
// Start pairing simulation, which will add a fake device and fake records.
fake_nfc_device_client_->BeginPairingSimulation(0, 0);
base::RunLoop().RunUntilIdle();
// Create the adapter.
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
// Observer shouldn't have received any calls, as it got created AFTER the
// notifications were sent.
EXPECT_EQ(0, observer.present_changed_count_);
EXPECT_EQ(0, observer.powered_changed_count_);
EXPECT_EQ(0, observer.polling_changed_count_);
EXPECT_EQ(0, observer.peer_count_);
EXPECT_TRUE(adapter_->IsPresent());
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_FALSE(adapter_->IsPolling());
NfcAdapter::PeerList peers;
adapter_->GetPeers(&peers);
EXPECT_EQ(static_cast<size_t>(1), peers.size());
NfcPeer* peer = peers[0];
const NfcNdefMessage& message = peer->GetNdefMessage();
EXPECT_EQ(static_cast<size_t>(3), message.records().size());
}
// Tests that tag and record objects are created for all tags and records that
// already exist when the adapter is created.
TEST_F(NfcChromeOSTest, TagsInitializedWhenAdapterCreated) {
const char kTestURI[] = "fake://path/for/testing";
// Set up the adapter client.
NfcAdapterClient::Properties* properties =
fake_nfc_adapter_client_->GetProperties(
dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0));
properties->powered.Set(true, base::Bind(&OnSet));
fake_nfc_adapter_client_->StartPollLoop(
dbus::ObjectPath(FakeNfcAdapterClient::kAdapterPath0),
nfc_adapter::kModeInitiator,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
base::Unretained(this)));
EXPECT_EQ(1, success_callback_count_);
EXPECT_TRUE(properties->powered.value());
EXPECT_TRUE(properties->polling.value());
// Add the fake tag.
fake_nfc_tag_client_->BeginPairingSimulation(0);
base::RunLoop().RunUntilIdle();
// Create a fake record.
base::DictionaryValue test_record_data;
test_record_data.SetString(nfc_record::kTypeProperty, nfc_record::kTypeUri);
test_record_data.SetString(nfc_record::kUriProperty, kTestURI);
fake_nfc_tag_client_->Write(
dbus::ObjectPath(FakeNfcTagClient::kTagPath),
test_record_data,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallbackWithParameters,
base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_);
// Create the adapter.
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
// Observer shouldn't have received any calls, as it got created AFTER the
// notifications were sent.
EXPECT_EQ(0, observer.present_changed_count_);
EXPECT_EQ(0, observer.powered_changed_count_);
EXPECT_EQ(0, observer.polling_changed_count_);
EXPECT_EQ(0, observer.peer_count_);
EXPECT_TRUE(adapter_->IsPresent());
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_FALSE(adapter_->IsPolling());
NfcAdapter::TagList tags;
adapter_->GetTags(&tags);
EXPECT_EQ(static_cast<size_t>(1), tags.size());
NfcTag* tag = tags[0];
const NfcNdefMessage& message = tag->GetNdefTagTechnology()->GetNdefMessage();
EXPECT_EQ(static_cast<size_t>(1), message.records().size());
const NfcNdefRecord* record = message.records()[0];
std::string uri;
EXPECT_TRUE(record->data().GetString(NfcNdefRecord::kFieldURI, &uri));
EXPECT_EQ(kTestURI, uri);
}
// Tests that the adapter correctly updates its state when polling is started
// and stopped.
TEST_F(NfcChromeOSTest, StartAndStopPolling) {
SetAdapter();
EXPECT_TRUE(adapter_->IsPresent());
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
// Start polling while not powered. Should fail.
EXPECT_FALSE(adapter_->IsPowered());
adapter_->StartPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(0, success_callback_count_);
EXPECT_EQ(1, error_callback_count_);
EXPECT_FALSE(adapter_->IsPolling());
// Start polling while powered. Should succeed.
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(1, success_callback_count_);
EXPECT_EQ(1, error_callback_count_);
EXPECT_TRUE(adapter_->IsPowered());
adapter_->StartPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_);
EXPECT_EQ(1, error_callback_count_);
EXPECT_TRUE(adapter_->IsPolling());
// Start polling while already polling. Should fail.
adapter_->StartPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_);
EXPECT_EQ(2, error_callback_count_);
EXPECT_TRUE(adapter_->IsPolling());
// Stop polling. Should succeed.
adapter_->StopPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(3, success_callback_count_);
EXPECT_EQ(2, error_callback_count_);
EXPECT_FALSE(adapter_->IsPolling());
// Stop polling while not polling. Should fail.
adapter_->StopPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(3, success_callback_count_);
EXPECT_EQ(3, error_callback_count_);
EXPECT_FALSE(adapter_->IsPolling());
}
// Tests a simple peer pairing simulation.
TEST_F(NfcChromeOSTest, PeerTest) {
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
adapter_->StartPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_);
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_TRUE(adapter_->IsPolling());
EXPECT_EQ(0, observer.peer_count_);
// Add the fake device.
fake_nfc_device_client_->BeginPairingSimulation(0, -1);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.peer_count_);
EXPECT_EQ(FakeNfcDeviceClient::kDevicePath, observer.peer_identifier_);
NfcPeer* peer = adapter_->GetPeer(observer.peer_identifier_);
CHECK(peer);
peer->AddObserver(&observer);
// Peer should have no records on it.
EXPECT_TRUE(peer->GetNdefMessage().records().empty());
EXPECT_EQ(0, observer.peer_records_received_count_);
// Make records visible.
fake_nfc_record_client_->SetDeviceRecordsVisible(true);
EXPECT_EQ(3, observer.peer_records_received_count_);
EXPECT_EQ(static_cast<size_t>(3), peer->GetNdefMessage().records().size());
// End the simulation. Peer should get removed.
fake_nfc_device_client_->EndPairingSimulation();
EXPECT_EQ(0, observer.peer_count_);
EXPECT_TRUE(observer.peer_identifier_.empty());
peer = adapter_->GetPeer(observer.peer_identifier_);
EXPECT_FALSE(peer);
// No record related notifications will be sent when a peer gets removed.
EXPECT_EQ(3, observer.peer_records_received_count_);
}
// Tests a simple tag pairing simulation.
TEST_F(NfcChromeOSTest, TagTest) {
const char kTestURI[] = "fake://path/for/testing";
SetAdapter();
TestObserver observer(adapter_);
adapter_->AddObserver(&observer);
adapter_->SetPowered(
true,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
adapter_->StartPolling(
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_);
EXPECT_TRUE(adapter_->IsPowered());
EXPECT_TRUE(adapter_->IsPolling());
EXPECT_EQ(0, observer.tag_count_);
// Add the fake tag.
fake_nfc_tag_client_->BeginPairingSimulation(0);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, observer.tag_count_);
EXPECT_EQ(FakeNfcTagClient::kTagPath, observer.tag_identifier_);
NfcTag* tag = adapter_->GetTag(observer.tag_identifier_);
CHECK(tag);
tag->AddObserver(&observer);
EXPECT_TRUE(tag->IsReady());
CHECK(tag->GetNdefTagTechnology());
tag->GetNdefTagTechnology()->AddObserver(&observer);
NfcNdefTagTechnology* tag_technology = tag->GetNdefTagTechnology();
EXPECT_TRUE(tag_technology->IsSupportedByTag());
// Tag should have no records on it.
EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty());
EXPECT_EQ(0, observer.tag_records_received_count_);
// Set the tag record visible. By default the record has no content, so no
// NfcNdefMessage should be received.
fake_nfc_record_client_->SetTagRecordsVisible(true);
EXPECT_TRUE(tag_technology->GetNdefMessage().records().empty());
EXPECT_EQ(0, observer.tag_records_received_count_);
fake_nfc_record_client_->SetTagRecordsVisible(false);
// Write an NDEF record to the tag.
EXPECT_EQ(2, success_callback_count_); // 2 for SetPowered and StartPolling.
EXPECT_EQ(0, error_callback_count_);
base::DictionaryValue record_data;
record_data.SetString(NfcNdefRecord::kFieldURI, kTestURI);
NfcNdefRecord written_record;
written_record.Populate(NfcNdefRecord::kTypeURI, &record_data);
NfcNdefMessage written_message;
written_message.AddRecord(&written_record);
tag_technology->WriteNdef(
written_message,
base::Bind(&NfcChromeOSTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NfcChromeOSTest::ErrorCallback,
base::Unretained(this)));
EXPECT_EQ(3, success_callback_count_);
EXPECT_EQ(0, error_callback_count_);
EXPECT_EQ(static_cast<size_t>(1),
tag_technology->GetNdefMessage().records().size());
EXPECT_EQ(1, observer.tag_records_received_count_);
NfcNdefRecord* received_record =
tag_technology->GetNdefMessage().records()[0];
EXPECT_EQ(NfcNdefRecord::kTypeURI, received_record->type());
std::string uri;
EXPECT_TRUE(received_record->data().GetString(
NfcNdefRecord::kFieldURI, &uri));
EXPECT_EQ(kTestURI, uri);
// End the simulation. Tag should get removed.
fake_nfc_tag_client_->EndPairingSimulation();
EXPECT_EQ(0, observer.tag_count_);
EXPECT_TRUE(observer.tag_identifier_.empty());
tag = adapter_->GetTag(observer.tag_identifier_);
EXPECT_FALSE(tag);
// No record related notifications will be sent when a tag gets removed.
EXPECT_EQ(1, observer.tag_records_received_count_);
}
// Unit tests for nfc_ndef_record_utils methods.
TEST_F(NfcChromeOSTest, NfcNdefRecordToDBusAttributes) {
const char kText[] = "text";
const char kURI[] = "test://uri";
const char kEncoding[] = "encoding";
const char kLanguageCode[] = "en";
const char kMimeType[] = "mime-type";
const double kSize = 5;
// Text record.
base::DictionaryValue data;
data.SetString(NfcNdefRecord::kFieldText, kText);
data.SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode);
data.SetString(NfcNdefRecord::kFieldEncoding, kEncoding);
std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord());
ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeText, &data));
base::DictionaryValue result;
EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
record.get(), &result));
std::string string_value;
EXPECT_TRUE(result.GetString(
nfc_record::kTypeProperty, &string_value));
EXPECT_EQ(nfc_record::kTypeText, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kRepresentationProperty, &string_value));
EXPECT_EQ(kText, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kLanguageProperty, &string_value));
EXPECT_EQ(kLanguageCode, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kEncodingProperty, &string_value));
EXPECT_EQ(kEncoding, string_value);
// URI record.
data.Clear();
data.SetString(NfcNdefRecord::kFieldURI, kURI);
data.SetString(NfcNdefRecord::kFieldMimeType, kMimeType);
data.SetDouble(NfcNdefRecord::kFieldTargetSize, kSize);
record.reset(new NfcNdefRecord());
ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data));
result.Clear();
EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
record.get(), &result));
EXPECT_TRUE(result.GetString(nfc_record::kTypeProperty, &string_value));
EXPECT_EQ(nfc_record::kTypeUri, string_value);
EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value));
EXPECT_EQ(kURI, string_value);
EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value));
EXPECT_EQ(kMimeType, string_value);
double double_value;
EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value));
EXPECT_EQ(kSize, double_value);
// SmartPoster record.
base::DictionaryValue* title = new base::DictionaryValue();
title->SetString(NfcNdefRecord::kFieldText, kText);
title->SetString(NfcNdefRecord::kFieldLanguageCode, kLanguageCode);
title->SetString(NfcNdefRecord::kFieldEncoding, kEncoding);
base::ListValue* titles = new base::ListValue();
titles->Append(title);
data.Set(NfcNdefRecord::kFieldTitles, titles);
record.reset(new NfcNdefRecord());
ASSERT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
result.Clear();
EXPECT_TRUE(nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
record.get(), &result));
EXPECT_TRUE(result.GetString(
nfc_record::kTypeProperty, &string_value));
EXPECT_EQ(nfc_record::kTypeSmartPoster, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kRepresentationProperty, &string_value));
EXPECT_EQ(kText, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kLanguageProperty, &string_value));
EXPECT_EQ(kLanguageCode, string_value);
EXPECT_TRUE(result.GetString(
nfc_record::kEncodingProperty, &string_value));
EXPECT_EQ(kEncoding, string_value);
EXPECT_TRUE(result.GetString(nfc_record::kUriProperty, &string_value));
EXPECT_EQ(kURI, string_value);
EXPECT_TRUE(result.GetString(nfc_record::kMimeTypeProperty, &string_value));
EXPECT_EQ(kMimeType, string_value);
EXPECT_TRUE(result.GetDouble(nfc_record::kSizeProperty, &double_value));
EXPECT_EQ(kSize, double_value);
}
TEST_F(NfcChromeOSTest, RecordPropertiesToNfcNdefRecord) {
const char kText[] = "text";
const char kURI[] = "test://uri";
const char kEncoding[] = "encoding";
const char kLanguageCode[] = "en";
const char kMimeType[] = "mime-type";
const uint32_t kSize = 5;
FakeNfcRecordClient::Properties record_properties(
base::Bind(&OnPropertyChangedCallback));
// Text record.
record_properties.type.ReplaceValue(nfc_record::kTypeText);
record_properties.representation.ReplaceValue(kText);
record_properties.language.ReplaceValue(kLanguageCode);
record_properties.encoding.ReplaceValue(kEncoding);
std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord());
EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
&record_properties, record.get()));
EXPECT_TRUE(record->IsPopulated());
std::string string_value;
EXPECT_EQ(NfcNdefRecord::kTypeText, record->type());
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldText, &string_value));
EXPECT_EQ(kText, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldLanguageCode, &string_value));
EXPECT_EQ(kLanguageCode, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldEncoding, &string_value));
EXPECT_EQ(kEncoding, string_value);
// URI record.
record_properties.representation.ReplaceValue("");
record_properties.language.ReplaceValue("");
record_properties.encoding.ReplaceValue("");
record_properties.type.ReplaceValue(nfc_record::kTypeUri);
record_properties.uri.ReplaceValue(kURI);
record_properties.mime_type.ReplaceValue(kMimeType);
record_properties.size.ReplaceValue(kSize);
record.reset(new NfcNdefRecord());
EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
&record_properties, record.get()));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeURI, record->type());
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldURI, &string_value));
EXPECT_EQ(kURI, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldMimeType, &string_value));
EXPECT_EQ(kMimeType, string_value);
double double_value;
EXPECT_TRUE(record->data().GetDouble(
NfcNdefRecord::kFieldTargetSize, &double_value));
EXPECT_EQ(kSize, double_value);
// Contents not matching type.
record_properties.representation.ReplaceValue(kText);
record_properties.language.ReplaceValue(kLanguageCode);
record_properties.encoding.ReplaceValue(kEncoding);
record.reset(new NfcNdefRecord());
EXPECT_FALSE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
&record_properties, record.get()));
EXPECT_FALSE(record->IsPopulated());
// SmartPoster record.
record_properties.type.ReplaceValue(nfc_record::kTypeSmartPoster);
EXPECT_TRUE(nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
&record_properties, record.get()));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeSmartPoster, record->type());
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldURI, &string_value));
EXPECT_EQ(kURI, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldMimeType, &string_value));
EXPECT_EQ(kMimeType, string_value);
EXPECT_TRUE(record->data().GetDouble(
NfcNdefRecord::kFieldTargetSize, &double_value));
EXPECT_EQ(kSize, double_value);
const base::ListValue* titles = NULL;
EXPECT_TRUE(record->data().GetList(NfcNdefRecord::kFieldTitles, &titles));
EXPECT_EQ(static_cast<size_t>(1), titles->GetSize());
ASSERT_TRUE(titles);
const base::DictionaryValue* title = NULL;
EXPECT_TRUE(titles->GetDictionary(0, &title));
CHECK(title);
EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldText, &string_value));
EXPECT_EQ(kText, string_value);
EXPECT_TRUE(title->GetString(
NfcNdefRecord::kFieldLanguageCode, &string_value));
EXPECT_EQ(kLanguageCode, string_value);
EXPECT_TRUE(title->GetString(NfcNdefRecord::kFieldEncoding, &string_value));
EXPECT_EQ(kEncoding, string_value);
}
} // namespace chromeos

@ -1,263 +0,0 @@
// 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 "device/nfc/nfc_ndef_record.h"
#include <stddef.h>
#include <stdint.h>
#include <map>
#include "base/logging.h"
#include "url/gurl.h"
using base::DictionaryValue;
using base::ListValue;
namespace device {
namespace {
typedef std::map<std::string, base::Value::Type> FieldValueMap;
bool ValidateURI(const DictionaryValue* data) {
std::string uri;
if (!data->GetString(NfcNdefRecord::kFieldURI, &uri)) {
VLOG(1) << "No URI entry in data.";
return false;
}
DCHECK(!uri.empty());
// Use GURL to check validity.
GURL url(uri);
if (!url.is_valid()) {
LOG(ERROR) << "Invalid URI given: " << uri;
return false;
}
return true;
}
bool CheckFieldsAreValid(
const FieldValueMap& required_fields,
const FieldValueMap& optional_fields,
const DictionaryValue* data) {
size_t required_count = 0;
for (DictionaryValue::Iterator iter(*data);
!iter.IsAtEnd(); iter.Advance()) {
FieldValueMap::const_iterator field_iter =
required_fields.find(iter.key());
if (field_iter == required_fields.end()) {
// Field wasn't one of the required fields. Check if optional.
field_iter = optional_fields.find(iter.key());
if (field_iter == optional_fields.end()) {
// If the field isn't one of the optional fields either, then it's
// invalid.
VLOG(1) << "Tried to populate record with invalid field: "
<< iter.key();
return false;
}
} else {
required_count++;
}
// The field is invalid, if the type of its value is incorrect.
if (field_iter->second != iter.value().GetType()) {
VLOG(1) << "Provided value for field \"" << iter.key() << "\" has type "
<< iter.value().GetType() << ", expected: "
<< field_iter->second;
return false;
}
// Make sure that the value is non-empty, if the value is a string.
std::string string_value;
if (iter.value().GetAsString(&string_value) && string_value.empty()) {
VLOG(1) << "Empty value given for field of type string: " << iter.key();
return false;
}
}
// Check for required fields.
if (required_count != required_fields.size()) {
VLOG(1) << "Provided data did not contain all required fields for "
<< "requested NDEF type.";
return false;
}
return true;
}
// Verifies that the contents of |data| conform to the fields of NDEF type
// "Text".
bool HandleTypeText(const DictionaryValue* data) {
VLOG(1) << "Populating record with type \"Text\".";
FieldValueMap required_fields;
required_fields[NfcNdefRecord::kFieldText] = base::Value::TYPE_STRING;
required_fields[NfcNdefRecord::kFieldEncoding] = base::Value::TYPE_STRING;
required_fields[NfcNdefRecord::kFieldLanguageCode] = base::Value::TYPE_STRING;
FieldValueMap optional_fields;
if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
VLOG(1) << "Failed to populate record.";
return false;
}
// Verify that the "Encoding" property has valid values.
std::string encoding;
if (!data->GetString(NfcNdefRecord::kFieldEncoding, &encoding)) {
if (encoding != NfcNdefRecord::kEncodingUtf8 ||
encoding != NfcNdefRecord::kEncodingUtf16) {
VLOG(1) << "Invalid \"Encoding\" value:" << encoding;
return false;
}
}
return true;
}
// Verifies that the contents of |data| conform to the fields of NDEF type
// "SmartPoster".
bool HandleTypeSmartPoster(const DictionaryValue* data) {
VLOG(1) << "Populating record with type \"SmartPoster\".";
FieldValueMap required_fields;
required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
FieldValueMap optional_fields;
optional_fields[NfcNdefRecord::kFieldAction] = base::Value::TYPE_STRING;
optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
// base::Value restricts the number types to BOOL, INTEGER, and DOUBLE only.
// uint32_t will automatically get converted to a double. "target size" is
// really a uint32_t but we define it as a double for this reason.
// (See dbus/values_util.h).
optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
optional_fields[NfcNdefRecord::kFieldTitles] = base::Value::TYPE_LIST;
if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
VLOG(1) << "Failed to populate record.";
return false;
}
// Verify that the "titles" field was formatted correctly, if it exists.
const ListValue* titles = NULL;
if (data->GetList(NfcNdefRecord::kFieldTitles, &titles)) {
if (titles->empty()) {
VLOG(1) << "\"titles\" field of SmartPoster is empty.";
return false;
}
for (ListValue::const_iterator iter = titles->begin();
iter != titles->end(); ++iter) {
const DictionaryValue* title_data = NULL;
if (!(*iter)->GetAsDictionary(&title_data)) {
VLOG(1) << "\"title\" entry for SmartPoster contains an invalid value "
<< "type";
return false;
}
if (!HandleTypeText(title_data)) {
VLOG(1) << "Badly formatted \"title\" entry for SmartPoster.";
return false;
}
}
}
return ValidateURI(data);
}
// Verifies that the contents of |data| conform to the fields of NDEF type
// "URI".
bool HandleTypeUri(const DictionaryValue* data) {
VLOG(1) << "Populating record with type \"URI\".";
FieldValueMap required_fields;
required_fields[NfcNdefRecord::kFieldURI] = base::Value::TYPE_STRING;
FieldValueMap optional_fields;
optional_fields[NfcNdefRecord::kFieldMimeType] = base::Value::TYPE_STRING;
optional_fields[NfcNdefRecord::kFieldTargetSize] = base::Value::TYPE_DOUBLE;
// Allow passing TargetSize as an integer, but convert it to a double.
if (!CheckFieldsAreValid(required_fields, optional_fields, data)) {
VLOG(1) << "Failed to populate record.";
return false;
}
return ValidateURI(data);
}
} // namespace
// static
const char NfcNdefRecord::kFieldEncoding[] = "encoding";
// static
const char NfcNdefRecord::kFieldLanguageCode[] = "languageCode";
// static
const char NfcNdefRecord::kFieldText[] = "text";
// static
const char NfcNdefRecord::kFieldURI[] = "uri";
// static
const char NfcNdefRecord::kFieldMimeType[] = "mimeType";
// static
const char NfcNdefRecord::kFieldTargetSize[] = "targetSize";
// static
const char NfcNdefRecord::kFieldTitles[] = "titles";
// static
const char NfcNdefRecord::kFieldAction[] = "action";
// static
const char NfcNdefRecord::kEncodingUtf8[] = "UTF-8";
// static
const char NfcNdefRecord::kEncodingUtf16[] = "UTF-16";
// static
const char NfcNdefRecord::kSmartPosterActionDo[] = "do";
// static
const char NfcNdefRecord::kSmartPosterActionSave[] = "save";
// static
const char NfcNdefRecord::kSmartPosterActionOpen[] = "open";
NfcNdefRecord::NfcNdefRecord() : type_(kTypeUnknown) {
}
NfcNdefRecord::~NfcNdefRecord() {
}
bool NfcNdefRecord::IsPopulated() const {
return type_ != kTypeUnknown;
}
bool NfcNdefRecord::Populate(Type type, const DictionaryValue* data) {
if (IsPopulated())
return false;
DCHECK(data_.empty());
// At this time, only "Text", "URI", and "SmartPoster" are supported.
bool result = false;
switch (type) {
case kTypeText:
result = HandleTypeText(data);
break;
case kTypeSmartPoster:
result = HandleTypeSmartPoster(data);
break;
case kTypeURI:
result = HandleTypeUri(data);
break;
default:
VLOG(1) << "Unsupported NDEF type: " << type;
break;
}
if (!result)
return false;
type_ = type;
data_.MergeDictionary(data);
return true;
}
NfcNdefMessage::NfcNdefMessage() {
}
NfcNdefMessage::~NfcNdefMessage() {
}
void NfcNdefMessage::AddRecord(NfcNdefRecord* record) {
records_.push_back(record);
}
bool NfcNdefMessage::RemoveRecord(NfcNdefRecord* record) {
for (RecordList::iterator iter = records_.begin();
iter != records_.end(); ++iter) {
if (*iter == record) {
records_.erase(iter);
return true;
}
}
return false;
}
} // namespace device

@ -1,168 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_NDEF_RECORD_H_
#define DEVICE_NFC_NFC_NDEF_RECORD_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/values.h"
namespace device {
// NfcNdefRecord represents an NDEF (NFC Data Exchange Format) record. NDEF is
// a light-weight binary format specified by the NFC Forum for transmission and
// storage of typed data over NFC. NDEF defines two constructs: NDEF records and
// messages. An NDEF record contains typed data, such as MIME-type media, a URI,
// or a custom application payload, whereas an NDEF message is a container for
// one or more NDEF records.
class NfcNdefRecord {
public:
// NDEF record types that define the payload of the NDEF record.
enum Type {
kTypeHandoverCarrier,
kTypeHandoverRequest,
kTypeHandoverSelect,
kTypeSmartPoster,
kTypeText,
kTypeURI,
kTypeUnknown
};
// The following are strings that define a possible field of an NDEF record.
// These strings are used as the keys in the dictionary returned by |data|.
// Not all fields are always present in an NDEF record, where the presence
// of a field depends on the type of the record. While some fields are
// required for a specific record type, others can be optional and won't
// always be present.
// Fields for type "Text".
// The character encoding. When present, the value is one of |kEncodingUtf8|
// and |kEncodingUtf16|. Otherwise, this field is optional.
static const char kFieldEncoding[];
// The ISO/IANA language code (e.g. "en" or "jp"). This field is optional.
static const char kFieldLanguageCode[];
// The human readable representation of a text. This field is mandatory.
static const char kFieldText[];
// Fields for type "URI".
// The complete URI, including the scheme and the resource. This field is
// required.
static const char kFieldURI[];
// The URI object MIME type. This is a description of the MIME type of the
// object the URI points at. This field is optional.
static const char kFieldMimeType[];
// The size of the object the URI points at. This field is optional.
// If present, the value is an unsigned integer. Since base/values.h does not
// define an unsigned integer type, use a base::DoubleValue to store this.
static const char kFieldTargetSize[];
// Fields for type "SmartPoster". A SmartPoster can contain all possible
// fields of a "URI" record, in addition to the following:
// The "title" of the SmartPoster. This is an optional field. If present, the
// value of this field is a list of dictionaries, where each dictionary
// contains the possible fields of a "Text" record. If the list contains
// more than one element, each element usually represents the same "title"
// text in a different language.
static const char kFieldTitles[];
// The suggested course of action. The value of this field is one of
// |kSmartPosterAction*|. This field is optional.
static const char kFieldAction[];
// Possible values for character encoding.
static const char kEncodingUtf8[];
static const char kEncodingUtf16[];
// Possible actions defined by the NFC forum SmartPoster record type. Each
// action is a suggestion to the application indicating the action it should
// take with the contents of the record.
// Do the action. e.g. open a URI, send an SMS, dial a phone number.
static const char kSmartPosterActionDo[];
// Store data, e.g. store an SMS, bookmark a URI, etc.
static const char kSmartPosterActionSave[];
// Open the data for editing.
static const char kSmartPosterActionOpen[];
NfcNdefRecord();
virtual ~NfcNdefRecord();
// Returns the type that defines the payload of this NDEF record.
Type type() const { return type_; }
// Returns the contents of this record in the form of a mapping from keys
// declared above to their stored values.
const base::DictionaryValue& data() const { return data_; }
// Returns true, if this record has been populated via a call to "Populate".
bool IsPopulated() const;
// Populates the record with the contents of |data| and sets its type to
// |type|. Returns true, if the record was successfully populated. If a
// failure occurs, e.g. |data| contains values that are not allowed in
// records of type |type| or if |data| does not contain mandatory fields of
// |type|, this method returns false. Populating an instance of an
// NfcNdefRecord is allowed only once and after a successful call to this
// method, all subsequent calls to this method will fail. Use IsPopulated()
// to determine if this record can be populated.
bool Populate(Type type, const base::DictionaryValue* data);
private:
// The type of this record.
Type type_;
// The contents of the record.
base::DictionaryValue data_;
DISALLOW_COPY_AND_ASSIGN(NfcNdefRecord);
};
// NfcNdefMessage represent an NDEF message. An NDEF message, contains one or
// more NDEF records and the order in which the records are stored dictates the
// order in which applications are meant to interpret them. For example, a
// client may decide to dispatch to applications based on the first record in
// the sequence.
class NfcNdefMessage {
public:
// Typedef for a list of NDEF records.
typedef std::vector<NfcNdefRecord*> RecordList;
NfcNdefMessage();
virtual ~NfcNdefMessage();
// The NDEF records that are contained in this message.
const RecordList& records() const { return records_; }
// Adds the NDEF record |record| to the sequence of records that this
// NfcNdefMessage contains. This method simply adds the record to this message
// and does NOT take ownership of it.
void AddRecord(NfcNdefRecord* record);
// Removes the NDEF record |record| from this message. Returns true, if the
// record was removed, otherwise returns false if |record| was not contained
// in this message.
bool RemoveRecord(NfcNdefRecord* record);
private:
// The NDEF records that are contained by this message.
RecordList records_;
DISALLOW_COPY_AND_ASSIGN(NfcNdefMessage);
};
} // namespace device
#endif // DEVICE_NFC_NFC_NDEF_RECORD_H_

@ -1,252 +0,0 @@
// 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 "device/nfc/nfc_ndef_record.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::DictionaryValue;
using base::ListValue;
using base::StringValue;
namespace device {
namespace {
const char kTestAction[] = "test-action";
const char kTestEncoding[] = "test-encoding";
const char kTestLanguageCode[] = "test-language-code";
const char kTestMimeType[] = "test-mime-type";
const uint32_t kTestTargetSize = 0;
const char kTestText[] = "test-text";
const char kTestURI[] = "test://uri";
} // namespace
TEST(NfcNdefRecordTest, PopulateTextRecord) {
DictionaryValue data;
std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord());
// Missing text field. Should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_FALSE(record->IsPopulated());
// Text field with incorrect type. Should fail.
data.SetInteger(NfcNdefRecord::kFieldText, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_FALSE(record->IsPopulated());
// Text field with correct type but missing encoding and language.
// Should fail.
data.SetString(NfcNdefRecord::kFieldText, kTestText);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_FALSE(record->IsPopulated());
// Populating a successfully populated record should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
// Incorrect type for language code.
data.SetInteger(NfcNdefRecord::kFieldLanguageCode, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_FALSE(record->IsPopulated());
// Correct type for language code, invalid encoding.
data.SetString(NfcNdefRecord::kFieldLanguageCode, kTestLanguageCode);
data.SetInteger(NfcNdefRecord::kFieldEncoding, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_FALSE(record->IsPopulated());
// All entries valid. Should succeed.
data.SetString(NfcNdefRecord::kFieldEncoding, kTestEncoding);
EXPECT_TRUE(record->Populate(NfcNdefRecord::kTypeText, &data));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeText, record->type());
// Compare record contents.
std::string string_value;
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldText, &string_value));
EXPECT_EQ(kTestText, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldLanguageCode, &string_value));
EXPECT_EQ(kTestLanguageCode, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldEncoding, &string_value));
EXPECT_EQ(kTestEncoding, string_value);
}
TEST(NfcNdefRecordTest, PopulateUriRecord) {
DictionaryValue data;
std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord());
// Missing URI field. Should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_FALSE(record->IsPopulated());
// URI field with incorrect type. Should fail.
data.SetInteger(NfcNdefRecord::kFieldURI, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_FALSE(record->IsPopulated());
// URI field with correct type but invalid format.
data.SetString(NfcNdefRecord::kFieldURI, "test.uri");
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_FALSE(record->IsPopulated());
data.SetString(NfcNdefRecord::kFieldURI, kTestURI);
EXPECT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeURI, record->type());
// Populating a successfully populated record should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
// Recycle the record.
record.reset(new NfcNdefRecord());
EXPECT_FALSE(record->IsPopulated());
// Incorrect optional fields. Should fail.
data.SetInteger(NfcNdefRecord::kFieldMimeType, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_FALSE(record->IsPopulated());
data.SetString(NfcNdefRecord::kFieldMimeType, kTestMimeType);
data.SetInteger(NfcNdefRecord::kFieldTargetSize, kTestTargetSize);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_FALSE(record->IsPopulated());
// Optional fields are correct. Should succeed.
data.SetDouble(NfcNdefRecord::kFieldTargetSize,
static_cast<double>(kTestTargetSize));
EXPECT_TRUE(record->Populate(NfcNdefRecord::kTypeURI, &data));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeURI, record->type());
// Compare record contents.
std::string string_value;
double double_value;
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldURI, &string_value));
EXPECT_EQ(kTestURI, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldMimeType, &string_value));
EXPECT_EQ(kTestMimeType, string_value);
EXPECT_TRUE(record->data().GetDouble(
NfcNdefRecord::kFieldTargetSize, &double_value));
EXPECT_EQ(kTestTargetSize, static_cast<uint32_t>(double_value));
}
TEST(NfcNdefRecordTest, PopulateSmartPoster) {
DictionaryValue data;
std::unique_ptr<NfcNdefRecord> record(new NfcNdefRecord());
// Missing URI field. Should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// URI field with incorrect entry. Should fail.
data.SetInteger(NfcNdefRecord::kFieldURI, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// URI field with correct entry. Should succeed.
data.SetString(NfcNdefRecord::kFieldURI, kTestURI);
EXPECT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_TRUE(record->IsPopulated());
EXPECT_EQ(NfcNdefRecord::kTypeSmartPoster, record->type());
// Populating a successfully populated record should fail.
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
// Recycle the record.
record.reset(new NfcNdefRecord());
EXPECT_FALSE(record->IsPopulated());
// Incorrect optional fields. Should fail.
data.SetInteger(NfcNdefRecord::kFieldAction, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
data.SetString(NfcNdefRecord::kFieldAction, kTestAction);
data.SetInteger(NfcNdefRecord::kFieldMimeType, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
data.SetString(NfcNdefRecord::kFieldMimeType, kTestMimeType);
data.SetInteger(NfcNdefRecord::kFieldTargetSize, kTestTargetSize);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
data.SetDouble(NfcNdefRecord::kFieldTargetSize, kTestTargetSize);
data.SetInteger(NfcNdefRecord::kFieldTitles, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// Empty titles value should fail.
ListValue* list_value = new ListValue();
data.Set(NfcNdefRecord::kFieldTitles, list_value);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// Title value with missing required field.
DictionaryValue* title_value = new DictionaryValue();
list_value->Append(title_value);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// Title value with invalid "text" field.
title_value->SetInteger(NfcNdefRecord::kFieldText, 0);
EXPECT_FALSE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_FALSE(record->IsPopulated());
// Title value with valid entries.
title_value->SetString(NfcNdefRecord::kFieldText, kTestText);
title_value->SetString(NfcNdefRecord::kFieldLanguageCode, kTestLanguageCode);
title_value->SetString(NfcNdefRecord::kFieldEncoding, kTestEncoding);
EXPECT_TRUE(record->Populate(NfcNdefRecord::kTypeSmartPoster, &data));
EXPECT_TRUE(record->IsPopulated());
// Verify the record contents.
std::string string_value;
double double_value;
const ListValue* const_list_value;
const DictionaryValue* const_dictionary_value;
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldURI, &string_value));
EXPECT_EQ(kTestURI, string_value);
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldMimeType, &string_value));
EXPECT_EQ(kTestMimeType, string_value);
EXPECT_TRUE(record->data().GetDouble(
NfcNdefRecord::kFieldTargetSize, &double_value));
EXPECT_EQ(kTestTargetSize, static_cast<uint32_t>(double_value));
EXPECT_TRUE(record->data().GetString(
NfcNdefRecord::kFieldAction, &string_value));
EXPECT_EQ(kTestAction, string_value);
EXPECT_TRUE(record->data().GetList(
NfcNdefRecord::kFieldTitles, &const_list_value));
EXPECT_EQ(static_cast<size_t>(1), const_list_value->GetSize());
EXPECT_TRUE(const_list_value->GetDictionary(0, &const_dictionary_value));
EXPECT_TRUE(const_dictionary_value->GetString(
NfcNdefRecord::kFieldText, &string_value));
EXPECT_EQ(kTestText, string_value);
EXPECT_TRUE(const_dictionary_value->GetString(
NfcNdefRecord::kFieldLanguageCode, &string_value));
EXPECT_EQ(kTestLanguageCode, string_value);
EXPECT_TRUE(const_dictionary_value->GetString(
NfcNdefRecord::kFieldEncoding, &string_value));
EXPECT_EQ(kTestEncoding, string_value);
}
} // namespace device

@ -1,239 +0,0 @@
// 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 "device/nfc/nfc_ndef_record_utils_chromeos.h"
#include <memory>
#include "base/logging.h"
#include "device/nfc/nfc_ndef_record.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using device::NfcNdefRecord;
namespace chromeos {
namespace nfc_ndef_record_utils {
namespace {
// Maps the NDEF type |type| as returned by neard to the corresponding
// device::NfcNdefRecord::Type value.
NfcNdefRecord::Type DBusRecordTypeValueToNfcNdefRecordType(
const std::string& type) {
if (type == nfc_record::kTypeSmartPoster)
return NfcNdefRecord::kTypeSmartPoster;
if (type == nfc_record::kTypeText)
return NfcNdefRecord::kTypeText;
if (type == nfc_record::kTypeUri)
return NfcNdefRecord::kTypeURI;
if (type == nfc_record::kTypeHandoverRequest)
return NfcNdefRecord::kTypeHandoverRequest;
if (type == nfc_record::kTypeHandoverSelect)
return NfcNdefRecord::kTypeHandoverSelect;
if (type == nfc_record::kTypeHandoverCarrier)
return NfcNdefRecord::kTypeHandoverCarrier;
return NfcNdefRecord::kTypeUnknown;
}
// Maps the NDEF type |type| given as a NFC C++ API enumeration to the
// corresponding string value defined by neard.
std::string NfcRecordTypeEnumToPropertyValue(NfcNdefRecord::Type type) {
switch (type) {
case NfcNdefRecord::kTypeSmartPoster:
return nfc_record::kTypeSmartPoster;
case NfcNdefRecord::kTypeText:
return nfc_record::kTypeText;
case NfcNdefRecord::kTypeURI:
return nfc_record::kTypeUri;
case NfcNdefRecord::kTypeHandoverRequest:
return nfc_record::kTypeHandoverRequest;
case NfcNdefRecord::kTypeHandoverSelect:
return nfc_record::kTypeHandoverSelect;
case NfcNdefRecord::kTypeHandoverCarrier:
return nfc_record::kTypeHandoverCarrier;
default:
return "";
}
}
// Maps the field name |field_name| given as defined in NfcNdefRecord to the
// Neard Record D-Bus property name. This handles all fields except for
// NfcNdefRecord::kFieldTitles and NfcNdefRecord::kFieldAction, which need
// special handling.
std::string NdefRecordFieldToDBusProperty(const std::string& field_name) {
if (field_name == NfcNdefRecord::kFieldEncoding)
return nfc_record::kEncodingProperty;
if (field_name == NfcNdefRecord::kFieldLanguageCode)
return nfc_record::kLanguageProperty;
if (field_name == NfcNdefRecord::kFieldText)
return nfc_record::kRepresentationProperty;
if (field_name == NfcNdefRecord::kFieldURI)
return nfc_record::kUriProperty;
if (field_name == NfcNdefRecord::kFieldMimeType)
return nfc_record::kMimeTypeProperty;
if (field_name == NfcNdefRecord::kFieldTargetSize)
return nfc_record::kSizeProperty;
return "";
}
std::string NfcNdefRecordActionValueToDBusActionValue(
const std::string& action) {
// TODO(armansito): Add bindings for values returned by neard to
// service_constants.h.
if (action == device::NfcNdefRecord::kSmartPosterActionDo)
return "Do";
if (action == device::NfcNdefRecord::kSmartPosterActionSave)
return "Save";
if (action == device::NfcNdefRecord::kSmartPosterActionOpen)
return "Edit";
return "";
}
std::string DBusActionValueToNfcNdefRecordActionValue(
const std::string& action) {
// TODO(armansito): Add bindings for values returned by neard to
// service_constants.h.
if (action == "Do")
return device::NfcNdefRecord::kSmartPosterActionDo;
if (action == "Save")
return device::NfcNdefRecord::kSmartPosterActionSave;
if (action == "Edit")
return device::NfcNdefRecord::kSmartPosterActionOpen;
return "";
}
// Translates the given dictionary of NDEF fields by recursively converting
// each key in |record_data| to its corresponding Record property name defined
// by the Neard D-Bus API. The output is stored in |out|. Returns false if an
// error occurs.
bool ConvertNdefFieldsToDBusAttributes(
const base::DictionaryValue& fields,
base::DictionaryValue* out) {
DCHECK(out);
for (base::DictionaryValue::Iterator iter(fields);
!iter.IsAtEnd(); iter.Advance()) {
// Special case the "titles" and "action" fields.
if (iter.key() == NfcNdefRecord::kFieldTitles) {
const base::ListValue* titles = NULL;
bool value_result = iter.value().GetAsList(&titles);
DCHECK(value_result);
DCHECK(titles->GetSize() != 0);
// TODO(armansito): For now, pick the first title in the list and write
// its contents directly to the top level of the field. This is due to an
// error in the Neard D-Bus API design. This code will need to be updated
// if the neard API changes to correct this.
const base::DictionaryValue* first_title = NULL;
value_result = titles->GetDictionary(0, &first_title);
DCHECK(value_result);
if (!ConvertNdefFieldsToDBusAttributes(*first_title, out)) {
LOG(ERROR) << "Invalid title field.";
return false;
}
} else if (iter.key() == NfcNdefRecord::kFieldAction) {
// The value of the action field needs to be translated.
std::string action_value;
bool value_result = iter.value().GetAsString(&action_value);
DCHECK(value_result);
std::string action =
NfcNdefRecordActionValueToDBusActionValue(action_value);
if (action.empty()) {
VLOG(1) << "Invalid action value: \"" << action_value << "\"";
return false;
}
out->SetString(nfc_record::kActionProperty, action);
} else {
std::string dbus_property = NdefRecordFieldToDBusProperty(iter.key());
if (dbus_property.empty()) {
LOG(ERROR) << "Invalid field: " << iter.key();
return false;
}
out->Set(dbus_property, iter.value().DeepCopy());
}
}
return true;
}
} // namespace
bool NfcNdefRecordToDBusAttributes(
const NfcNdefRecord* record,
base::DictionaryValue* out) {
DCHECK(record);
DCHECK(out);
if (!record->IsPopulated()) {
LOG(ERROR) << "Record is not populated.";
return false;
}
out->SetString(nfc_record::kTypeProperty,
NfcRecordTypeEnumToPropertyValue(record->type()));
return ConvertNdefFieldsToDBusAttributes(record->data(), out);
}
bool RecordPropertiesToNfcNdefRecord(
const NfcRecordClient::Properties* properties,
device::NfcNdefRecord* out) {
if (out->IsPopulated()) {
LOG(ERROR) << "Record is already populated!";
return false;
}
NfcNdefRecord::Type type =
DBusRecordTypeValueToNfcNdefRecordType(properties->type.value());
if (type == NfcNdefRecord::kTypeUnknown) {
LOG(ERROR) << "Record type is unknown.";
return false;
}
// Extract each property.
base::DictionaryValue attributes;
if (!properties->uri.value().empty())
attributes.SetString(NfcNdefRecord::kFieldURI, properties->uri.value());
if (!properties->mime_type.value().empty()) {
attributes.SetString(NfcNdefRecord::kFieldMimeType,
properties->mime_type.value());
}
if (properties->size.value() != 0) {
attributes.SetDouble(NfcNdefRecord::kFieldTargetSize,
static_cast<double>(properties->size.value()));
}
std::string action_value =
DBusActionValueToNfcNdefRecordActionValue(properties->action.value());
if (!action_value.empty())
attributes.SetString(NfcNdefRecord::kFieldAction, action_value);
// The "representation", "encoding", and "language" properties will be stored
// differently, depending on whether the record type is "SmartPoster" or
// "Text".
{
std::unique_ptr<base::DictionaryValue> text_attributes(
new base::DictionaryValue());
if (!properties->representation.value().empty()) {
text_attributes->SetString(NfcNdefRecord::kFieldText,
properties->representation.value());
}
if (!properties->encoding.value().empty()) {
text_attributes->SetString(NfcNdefRecord::kFieldEncoding,
properties->encoding.value());
}
if (!properties->language.value().empty()) {
text_attributes->SetString(NfcNdefRecord::kFieldLanguageCode,
properties->language.value());
}
if (!text_attributes->empty()) {
if (type == NfcNdefRecord::kTypeSmartPoster) {
base::ListValue* titles = new base::ListValue();
titles->Append(text_attributes.release());
attributes.Set(NfcNdefRecord::kFieldTitles, titles);
} else {
attributes.MergeDictionary(text_attributes.get());
}
}
}
// Populate the given record.
return out->Populate(type, &attributes);
}
} // namespace nfc_ndef_record_utils
} // namespace chromeos

@ -1,36 +0,0 @@
// 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 "base/values.h"
#include "chromeos/dbus/nfc_record_client.h"
#ifndef DEVICE_NFC_CHROMEOS_NDEF_RECORD_UTILS_CHROMEOS_H_
#define DEVICE_NFC_CHROMEOS_NDEF_RECORD_UTILS_CHROMEOS_H_
namespace device {
class NfcNdefRecord;
} // namespace device
namespace chromeos {
namespace nfc_ndef_record_utils {
// Converts the NfcNdefRecord |record| to a dictionary that can be passed to
// NfcDeviceClient::Push and NfcTagClient::Write and stores it in |out|.
// Returns false, if an error occurs during conversion.
bool NfcNdefRecordToDBusAttributes(
const device::NfcNdefRecord* record,
base::DictionaryValue* out);
// Converts an NDEF record D-Bus properties structure to an NfcNdefRecord
// instance by populating the instance passed in |out|. |out| must not be NULL
// and must not be already populated. Returns false, if an error occurs during
// conversion.
bool RecordPropertiesToNfcNdefRecord(
const NfcRecordClient::Properties* properties,
device::NfcNdefRecord* out);
} // namespace nfc_ndef_record_utils
} // namespace chromeos
#endif // DEVICE_NFC_CHROMEOS_NDEF_RECORD_UTILS_CHROMEOS_H_

@ -1,15 +0,0 @@
// 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 "device/nfc/nfc_peer.h"
namespace device {
NfcPeer::NfcPeer() {
}
NfcPeer::~NfcPeer() {
}
} // namespace device

@ -1,93 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_PEER_H_
#define DEVICE_NFC_NFC_PEER_H_
#include <map>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "device/nfc/nfc_ndef_record.h"
namespace device {
// NfcPeer represents a remote NFC adapter that is available for P2P
// communication with the local adapter. Instances of NfcPeer allow two
// kinds of P2P interaction that is supported by NFC:
//
// - NDEF. Specifically, reading NDEF records found on the peer device and
// pushing NDEF records to it (e.g. via SNEP or Android Beam), in the form
// of an NDEF message as specified by the NFC forum.
// - Initiating a handover. On platforms that support it, handover can be
// used to quickly bootstrap a Bluetooth or WiFi based connection between
// the two devices over NFC.
class NfcPeer {
public:
// NFC handover types.
enum HandoverType {
kHandoverTypeBluetooth,
kHandoverTypeWiFi
};
// Interface for observing changes from NFC peer devices.
class Observer {
public:
virtual ~Observer() {}
// This method will be called when an NDEF record |record| from the peer
// device |peer| is received. Users can use this method to be notified of
// new records on the device and when the initial set of records are
// received from it, if any. All records received from |peer| can be
// accessed by calling |peer->GetNdefMessage()|.
virtual void RecordReceived(NfcPeer* peer, const NfcNdefRecord* record) {}
};
// The ErrorCallback is used by methods to asynchronously report errors.
typedef base::Closure ErrorCallback;
virtual ~NfcPeer();
// Adds and removes observers for events on this NFC peer. If monitoring
// multiple peers, check the |peer| parameter of observer methods to
// determine which peer is issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the unique identifier assigned to this peer.
virtual std::string GetIdentifier() const = 0;
// Returns all NDEF records that were received from the peer device in the
// form of a NDEF message. If the returned NDEF message contains no records,
// this only means that no records have yet been received from the device.
// Users should use this method in conjunction with the Observer methods
// to be notified when the records are ready.
virtual const NfcNdefMessage& GetNdefMessage() const = 0;
// Sends the NDEF records contained in |message| to the peer device. On
// success, |callback| will be invoked. On failure, |error_callback| will be
// invoked.
virtual void PushNdef(const NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Initiates WiFi or Bluetooth pairing with the NFC peer device based on
// |handover_type|. On success, |callback| will be invoked. On failure,
// |error_callback| will be invoked.
virtual void StartHandover(HandoverType handover_type,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
protected:
NfcPeer();
private:
DISALLOW_COPY_AND_ASSIGN(NfcPeer);
};
} // namespace device
#endif // DEVICE_NFC_NFC_PEER_H_

@ -1,194 +0,0 @@
// 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 "device/nfc/nfc_peer_chromeos.h"
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/stl_util.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/nfc_device_client.h"
#include "device/nfc/nfc_ndef_record_utils_chromeos.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using device::NfcNdefMessage;
using device::NfcNdefRecord;
namespace chromeos {
namespace {
typedef std::vector<dbus::ObjectPath> ObjectPathVector;
} // namespace
NfcPeerChromeOS::NfcPeerChromeOS(const dbus::ObjectPath& object_path)
: object_path_(object_path),
weak_ptr_factory_(this) {
// Create record objects for all records that were received before.
const ObjectPathVector& records =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetRecordsForDevice(object_path_);
for (ObjectPathVector::const_iterator iter = records.begin();
iter != records.end(); ++iter) {
AddRecord(*iter);
}
DBusThreadManager::Get()->GetNfcRecordClient()->AddObserver(this);
}
NfcPeerChromeOS::~NfcPeerChromeOS() {
DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this);
base::STLDeleteValues(&records_);
}
void NfcPeerChromeOS::AddObserver(device::NfcPeer::Observer* observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void NfcPeerChromeOS::RemoveObserver(device::NfcPeer::Observer* observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
std::string NfcPeerChromeOS::GetIdentifier() const {
return object_path_.value();
}
const NfcNdefMessage& NfcPeerChromeOS::GetNdefMessage() const {
return message_;
}
void NfcPeerChromeOS::PushNdef(const NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (message.records().empty()) {
LOG(ERROR) << "Given NDEF message is empty. Cannot push it.";
error_callback.Run();
return;
}
// TODO(armansito): neard currently supports pushing only one NDEF record
// to a remote device and won't support multiple records until 0.15. Until
// then, report failure if |message| contains more than one record.
if (message.records().size() > 1) {
LOG(ERROR) << "Currently, pushing only 1 NDEF record is supported.";
error_callback.Run();
return;
}
const NfcNdefRecord* record = message.records()[0];
base::DictionaryValue attributes;
if (!nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
record, &attributes)) {
LOG(ERROR) << "Failed to extract NDEF record fields for NDEF push.";
error_callback.Run();
return;
}
DBusThreadManager::Get()->GetNfcDeviceClient()->Push(
object_path_,
attributes,
base::Bind(&NfcPeerChromeOS::OnPushNdef,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&NfcPeerChromeOS::OnPushNdefError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}
void NfcPeerChromeOS::StartHandover(HandoverType handover_type,
const base::Closure& callback,
const ErrorCallback& error_callback) {
// TODO(armansito): Initiating handover with a peer is currently not
// supported. For now, return an error immediately.
LOG(ERROR) << "NFC Handover currently not supported.";
error_callback.Run();
}
void NfcPeerChromeOS::RecordAdded(const dbus::ObjectPath& object_path) {
// Don't create the record object yet. Instead, wait until all record
// properties have been received and contruct the object and notify observers
// then.
VLOG(1) << "Record added: " << object_path.value() << ". Waiting until "
<< "all properties have been fetched to create record object.";
}
void NfcPeerChromeOS::RecordRemoved(const dbus::ObjectPath& object_path) {
NdefRecordMap::iterator iter = records_.find(object_path);
if (iter == records_.end())
return;
VLOG(1) << "Lost remote NDEF record object: " << object_path.value()
<< ", removing record.";
NfcNdefRecord* record = iter->second;
message_.RemoveRecord(record);
delete record;
records_.erase(iter);
}
void NfcPeerChromeOS::RecordPropertiesReceived(
const dbus::ObjectPath& object_path) {
VLOG(1) << "Record properties received for: " << object_path.value();
// Check if the found record belongs to this device.
bool record_found = false;
const ObjectPathVector& records =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetRecordsForDevice(object_path_);
for (ObjectPathVector::const_iterator iter = records.begin();
iter != records.end(); ++iter) {
if (*iter == object_path) {
record_found = true;
break;
}
}
if (!record_found) {
VLOG(1) << "Record \"" << object_path.value() << "\" doesn't belong to this"
<< " device. Ignoring.";
return;
}
AddRecord(object_path);
}
void NfcPeerChromeOS::OnPushNdef(const base::Closure& callback) {
callback.Run();
}
void NfcPeerChromeOS::OnPushNdefError(const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(ERROR) << object_path_.value() << ": Failed to Push NDEF message: "
<< error_name << ": " << error_message;
error_callback.Run();
}
void NfcPeerChromeOS::AddRecord(const dbus::ObjectPath& object_path) {
// Ignore this call if an entry for this record already exists.
if (records_.find(object_path) != records_.end()) {
VLOG(1) << "Record object for remote \"" << object_path.value()
<< "\" already exists.";
return;
}
NfcRecordClient::Properties* record_properties =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetProperties(object_path);
DCHECK(record_properties);
NfcNdefRecord* record = new NfcNdefRecord();
if (!nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
record_properties, record)) {
LOG(ERROR) << "Failed to create record object for record with object "
<< "path \"" << object_path.value() << "\"";
delete record;
return;
}
message_.AddRecord(record);
records_[object_path] = record;
FOR_EACH_OBSERVER(NfcPeer::Observer, observers_,
RecordReceived(this, record));
}
} // namespace chromeos

@ -1,81 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_PEER_CHROMEOS_H_
#define DEVICE_NFC_NFC_PEER_CHROMEOS_H_
#include <map>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "dbus/object_path.h"
#include "device/nfc/nfc_ndef_record.h"
#include "device/nfc/nfc_peer.h"
namespace chromeos {
// The NfcPeerChromeOS class implements NfcPeer for the Chrome OS platform.
class NfcPeerChromeOS : public device::NfcPeer,
public NfcRecordClient::Observer {
public:
// NfcPeer overrides.
void AddObserver(device::NfcPeer::Observer* observer) override;
void RemoveObserver(device::NfcPeer::Observer* observer) override;
std::string GetIdentifier() const override;
const device::NfcNdefMessage& GetNdefMessage() const override;
void PushNdef(const device::NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void StartHandover(HandoverType handover_type,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
private:
friend class NfcAdapterChromeOS;
// Mapping from D-Bus object paths to NfcNdefRecord objects.
typedef std::map<dbus::ObjectPath, device::NfcNdefRecord*> NdefRecordMap;
explicit NfcPeerChromeOS(const dbus::ObjectPath& object_path);
~NfcPeerChromeOS() override;
// NfcRecordClient::Observer overrides.
void RecordAdded(const dbus::ObjectPath& object_path) override;
void RecordRemoved(const dbus::ObjectPath& object_path) override;
void RecordPropertiesReceived(const dbus::ObjectPath& object_path) override;
// Called by dbus:: on completion of the D-Bus method call to push an NDEF.
void OnPushNdef(const base::Closure& callback);
void OnPushNdefError(const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Creates a record object for the record with object path |object_path| and
// notifies the observers, if a record object did not already exist for it.
void AddRecord(const dbus::ObjectPath& object_path);
// Object path of the peer that we are currently tracking.
dbus::ObjectPath object_path_;
// A map containing the NDEF records that were received from the peer.
NdefRecordMap records_;
// Message instance that contains pointers to all created records.
device::NfcNdefMessage message_;
// List of observers interested in event notifications from us.
base::ObserverList<device::NfcPeer::Observer> observers_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcPeerChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcPeerChromeOS);
};
} // namespace chromeos
#endif // DEVICE_NFC_NFC_PEER_CHROMEOS_H_

@ -1,15 +0,0 @@
// 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 "device/nfc/nfc_tag.h"
namespace device {
NfcTag::NfcTag() {
}
NfcTag::~NfcTag() {
}
} // namespace device

@ -1,113 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_TAG_H_
#define DEVICE_NFC_NFC_TAG_H_
#include "base/macros.h"
#include "device/nfc/nfc_tag_technology.h"
namespace device {
// NfcTag represents a remote NFC tag. An NFC tag is a passive NFC device,
// powered by the NFC field of the local adapter while it is in range. Tags
// can come in many forms, such as stickers, key fobs, or even embedded in a
// more sofisticated device.
//
// Tags can have a wide range of capabilities. Simple tags just offer
// read/write semantics, and contain some one time programmable areas to make
// read-only. More complex tags offer math operations and per-sector access
// control and authentication. The most sophisticated tags contain operating
// environments allowing complex interactions with the code executing on the
// tag.
//
// The NfcTag class facilitates possible interactions with a tag. The most
// common usage of a tag is to exchange NDEF messages, but different kinds of
// I/O can be performed using the NfcTagTechnology classes.
class NfcTag {
public:
// NFC tag types.
enum TagType {
kTagType1,
kTagType2,
kTagType3,
kTagType4,
kTagTypeUnknown,
};
// NFC protocols that a tag can support. A tag will usually support only one
// of these.
enum Protocol {
kProtocolFelica,
kProtocolIsoDep,
kProtocolJewel,
kProtocolMifare,
kProtocolNfcDep,
kProtocolUnknown
};
// Interface for observing changes from NFC tags.
class Observer {
public:
virtual ~Observer() {}
// Called when the tag type has been determined.
virtual void TagTypeChanged(NfcTag* tag, TagType type) {}
// Called when the write access to the tag has been determined or changed.
virtual void TagWritePermissionChanged(NfcTag* tag, bool read_only) {}
// Called when the underlying NFC protocol has been determined.
virtual void TagSupportedProtocolChanged(NfcTag* tag, Protocol protocol) {}
// Called when all initial values of the tag properties have been received
// from the remote tag and |tag| is ready to use.
virtual void TagReady(NfcTag* tag) {}
};
virtual ~NfcTag();
// Adds and removes observers for events on this NFC tag. If monitoring
// multiple tags, check the |tag| parameter of observer methods to determine
// which tag is issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Returns the unique identifier assigned to this tag.
virtual std::string GetIdentifier() const = 0;
// Returns the current tag's NFC forum specified "type".
virtual TagType GetType() const = 0;
// Returns true, if this tag is read-only and cannot be written to.
virtual bool IsReadOnly() const = 0;
// Returns the current tag's supported NFC protocol.
virtual Protocol GetSupportedProtocol() const = 0;
// Returns a bitmask of the tag I/O technologies supported by this tag.
virtual NfcTagTechnology::TechnologyTypeMask
GetSupportedTechnologies() const = 0;
// Returns true, if all tag properties have been received from the remote tag
// and this object is ready to use.
virtual bool IsReady() const = 0;
// Returns a pointer to the NDEF technology object that allows I/O on NDEF
// records. If NDEF is not supported by this tag, operations that are
// performed on the returned instance may not succeed. Users can determine
// support by calling NfcTagTechnology::IsSupportedByTag. The returned
// instance is owned by this tag.
virtual NfcNdefTagTechnology* GetNdefTagTechnology() = 0;
protected:
NfcTag();
private:
DISALLOW_COPY_AND_ASSIGN(NfcTag);
};
} // namespace device
#endif // DEVICE_NFC_NFC_TAG_H_

@ -1,164 +0,0 @@
// Copyright 2014 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 "device/nfc/nfc_tag_chromeos.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "device/nfc/nfc_tag_technology_chromeos.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using device::NfcTag;
using device::NfcTagTechnology;
using device::NfcNdefTagTechnology;
namespace chromeos {
namespace {
// Converts an NFC tag type value returned by neard to a NfcTag::TagType enum
// value.
NfcTag::TagType DBusTypePropertyToTagType(const std::string& type) {
if (type == nfc_tag::kTagType1)
return NfcTag::kTagType1;
if (type == nfc_tag::kTagType2)
return NfcTag::kTagType2;
if (type == nfc_tag::kTagType3)
return NfcTag::kTagType3;
if (type == nfc_tag::kTagType4)
return NfcTag::kTagType4;
return NfcTag::kTagTypeUnknown;
}
// Converts an NFC tag protocol value returned by neard to a NfcTag::Protocol
// enum value.
NfcTag::Protocol DBusProtocolPropertyToTagProtocol(
const std::string& protocol) {
if (protocol == nfc_common::kProtocolFelica)
return NfcTag::kProtocolFelica;
if (protocol == nfc_common::kProtocolIsoDep)
return NfcTag::kProtocolIsoDep;
if (protocol == nfc_common::kProtocolJewel)
return NfcTag::kProtocolJewel;
if (protocol == nfc_common::kProtocolMifare)
return NfcTag::kProtocolMifare;
if (protocol == nfc_common::kProtocolNfcDep)
return NfcTag::kProtocolNfcDep;
return NfcTag::kProtocolUnknown;
}
} // namespace
NfcTagChromeOS::NfcTagChromeOS(const dbus::ObjectPath& object_path)
: object_path_(object_path),
is_ready_(false),
ndef_technology_(new NfcNdefTagTechnologyChromeOS(this)) {
DBusThreadManager::Get()->GetNfcTagClient()->AddObserver(this);
}
NfcTagChromeOS::~NfcTagChromeOS() {
DBusThreadManager::Get()->GetNfcTagClient()->RemoveObserver(this);
}
void NfcTagChromeOS::AddObserver(NfcTag::Observer* observer) {
observers_.AddObserver(observer);
}
void NfcTagChromeOS::RemoveObserver(NfcTag::Observer* observer) {
observers_.RemoveObserver(observer);
}
std::string NfcTagChromeOS::GetIdentifier() const {
return object_path_.value();
}
NfcTag::TagType NfcTagChromeOS::GetType() const {
DCHECK(object_path_.IsValid());
return DBusTypePropertyToTagType(
DBusThreadManager::Get()->GetNfcTagClient()->
GetProperties(object_path_)->type.value());
}
bool NfcTagChromeOS::IsReadOnly() const {
DCHECK(object_path_.IsValid());
return DBusThreadManager::Get()->GetNfcTagClient()->
GetProperties(object_path_)->read_only.value();
}
NfcTag::Protocol NfcTagChromeOS::GetSupportedProtocol() const {
DCHECK(object_path_.IsValid());
return DBusProtocolPropertyToTagProtocol(
DBusThreadManager::Get()->GetNfcTagClient()->
GetProperties(object_path_)->protocol.value());
}
NfcTagTechnology::TechnologyTypeMask
NfcTagChromeOS::GetSupportedTechnologies() const {
// Determine supported technologies based on the tag's protocol and
// type.
NfcTag::TagType type = GetType();
NfcTag::Protocol protocol = GetSupportedProtocol();
if (type == NfcTag::kTagTypeUnknown || protocol == kProtocolUnknown) {
VLOG(1) << "Tag type and protocol unknown.";
return 0;
}
NfcTagTechnology::TechnologyTypeMask technologies = 0;
technologies |= NfcTagTechnology::kTechnologyTypeNdef;
if (type == NfcTag::kTagType3) {
DCHECK(protocol == NfcTag::kProtocolFelica);
return technologies | NfcTagTechnology::kTechnologyTypeNfcF;
}
if (protocol == NfcTag::kProtocolIsoDep) {
DCHECK(type == NfcTag::kTagType4);
technologies |= NfcTagTechnology::kTechnologyTypeIsoDep;
// TODO(armansito): Neard doesn't provide enough information to determine
// if the underlying wave-form is type A or type B. For now, report
// neither.
return technologies;
}
return technologies | NfcTagTechnology::kTechnologyTypeNfcA;
}
bool NfcTagChromeOS::IsReady() const {
return is_ready_;
}
NfcNdefTagTechnology* NfcTagChromeOS::GetNdefTagTechnology() {
return ndef_technology_.get();
}
void NfcTagChromeOS::TagPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {
if (object_path != object_path_)
return;
NfcTagClient::Properties* properties =
DBusThreadManager::Get()->GetNfcTagClient()->GetProperties(object_path_);
DCHECK(properties);
if (property_name == properties->type.name()) {
FOR_EACH_OBSERVER(NfcTag::Observer, observers_,
TagTypeChanged(this, GetType()));
} else if (property_name == properties->read_only.name()) {
FOR_EACH_OBSERVER(NfcTag::Observer, observers_,
TagWritePermissionChanged(this, IsReadOnly()));
} else if (property_name == properties->protocol.name()) {
FOR_EACH_OBSERVER(
NfcTag::Observer, observers_,
TagSupportedProtocolChanged(this, GetSupportedProtocol()));
}
}
void NfcTagChromeOS::TagPropertiesReceived(
const dbus::ObjectPath& object_path) {
if (is_ready_ || object_path != object_path_)
return;
is_ready_ = true;
FOR_EACH_OBSERVER(NfcTag::Observer, observers_, TagReady(this));
}
} // namespace chromeos

@ -1,70 +0,0 @@
// Copyright 2014 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.
#ifndef DEVICE_NFC_NFC_TAG_CHROMEOS_H_
#define DEVICE_NFC_NFC_TAG_CHROMEOS_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_tag_client.h"
#include "dbus/object_path.h"
#include "device/nfc/nfc_tag.h"
namespace chromeos {
class NfcNdefTagTechnologyChromeOS;
// The NfcTagChromeOS class implements device::NfcTag for the Chrome OS
// platform.
class NfcTagChromeOS : public device::NfcTag,
public NfcTagClient::Observer {
public:
// device::NfcTag overrides.
void AddObserver(device::NfcTag::Observer* observer) override;
void RemoveObserver(device::NfcTag::Observer* observer) override;
std::string GetIdentifier() const override;
TagType GetType() const override;
bool IsReadOnly() const override;
device::NfcTag::Protocol GetSupportedProtocol() const override;
device::NfcTagTechnology::TechnologyTypeMask GetSupportedTechnologies()
const override;
bool IsReady() const override;
device::NfcNdefTagTechnology* GetNdefTagTechnology() override;
// NfcTagClient::Observer overrides.
void TagPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) override;
void TagPropertiesReceived(const dbus::ObjectPath& object_path) override;
// Object path representing the remote tag object.
const dbus::ObjectPath& object_path() const { return object_path_; }
private:
friend class NfcAdapterChromeOS;
explicit NfcTagChromeOS(const dbus::ObjectPath& object_path);
~NfcTagChromeOS() override;
// Object path of the tag that we are currently tracking.
dbus::ObjectPath object_path_;
// Stores whether or not the initial set of properties have been received.
bool is_ready_;
// The NfcNdefTagTechnology instance that allows users to perform NDEF
// read and write on this tag.
std::unique_ptr<NfcNdefTagTechnologyChromeOS> ndef_technology_;
// List of observers interested in event notifications from us.
base::ObserverList<device::NfcTag::Observer> observers_;
DISALLOW_COPY_AND_ASSIGN(NfcTagChromeOS);
};
} // namespace chromeos
#endif // DEVICE_NFC_NFC_TAG_CHROMEOS_H_

@ -1,32 +0,0 @@
// 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 "device/nfc/nfc_tag_technology.h"
#include "device/nfc/nfc_tag.h"
namespace device {
NfcTagTechnology::NfcTagTechnology(NfcTag* tag) : tag_(tag) {
}
NfcTagTechnology::NfcTagTechnology() : tag_(NULL) {
}
NfcTagTechnology::~NfcTagTechnology() {
}
bool NfcNdefTagTechnology::IsSupportedByTag() const {
return tag() && (tag()->GetSupportedTechnologies() &
NfcTagTechnology::kTechnologyTypeNdef);
}
NfcNdefTagTechnology::NfcNdefTagTechnology(NfcTag* tag)
: NfcTagTechnology(tag) {
}
NfcNdefTagTechnology::~NfcNdefTagTechnology() {
}
} // namespace device

@ -1,126 +0,0 @@
// 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.
#ifndef DEVICE_NFC_NFC_TAG_TECHNOLOGY_H_
#define DEVICE_NFC_NFC_TAG_TECHNOLOGY_H_
#include <stdint.h>
#include "base/callback.h"
#include "base/macros.h"
#include "device/nfc/nfc_ndef_record.h"
namespace device {
class NfcTag;
// NfcTagTechnology represents an NFC technology that allows a certain type of
// I/O operation on an NFC tag. NFC tags can support a wide array of protocols.
// The NfcTagTechnology hierarchy allows both raw and high-level I/O operations
// on NFC tags. Do not create instances of these objects directly. Instead,
// obtain a handle directly from an NfcTag object.
class NfcTagTechnology {
public:
// The various I/O technologies that an NFC tag can support.
enum TechnologyType {
kTechnologyTypeNfcA = 1 << 0,
kTechnologyTypeNfcB = 1 << 1,
kTechnologyTypeNfcF = 1 << 2,
kTechnologyTypeNfcV = 1 << 3,
kTechnologyTypeIsoDep = 1 << 4,
kTechnologyTypeNdef = 1 << 5
};
typedef uint32_t TechnologyTypeMask;
virtual ~NfcTagTechnology();
// Returns true, if the underlying tag supports the NFC tag technology that
// this instance represents.
virtual bool IsSupportedByTag() const = 0;
// Returns a pointer to the associated NfcTag instance.
NfcTag* tag() const { return tag_; }
protected:
// Constructs a technology instance, where |tag| is the NFC tag that this
// instance will operate on. Clients aren't allowed to instantiate classes
// directly. They should use the static "Create" methods defined in each
// subclass to obtain the platform specific implementation.
explicit NfcTagTechnology(NfcTag* tag);
private:
NfcTagTechnology();
// The underlying NfcTag instance that data exchange operations through this
// instance are performed on.
NfcTag* tag_;
DISALLOW_COPY_AND_ASSIGN(NfcTagTechnology);
};
// NfcNdefTagTechnology allows reading and writing NDEF messages to a tag. This
// is the most commonly used data exchange format in NFC. NDEF is a data
// exchange format and is the top most layer of the protocol stack. NDEF itself
// is not a protocol; data is typically formatted in a way that is defined by
// the NDEF format and then transmitted via one of the underlying protocols.
// Hence all tags are capable of NDEF data exchange, however, all tags don't
// necessarily use NDEF to operate (e.g. a tag may contain a smart chip that
// does data processing on ISO-DEP based APDUs and ignores NDEF). This is why,
// even if a tag inherently supports NDEF, operations done via this class may
// not necessarily succeed.
class NfcNdefTagTechnology : public NfcTagTechnology {
public:
// The ErrorCallback is used by methods to asynchronously report errors.
typedef base::Closure ErrorCallback;
~NfcNdefTagTechnology() override;
// Interface for observing changes from NFC tags related to NDEF records.
class Observer {
public:
virtual ~Observer() {}
// This method will be called when an NDEF record |record|, stored on the
// NFC tag |tag| has been read. This method will be called multiple times
// as records are read from the tag or when the tag's records change (e.g.
// when the tag has been rewritten). All received records can be accessed by
// calling GetNdefMessage().
virtual void RecordReceived(NfcTag* tag, const NfcNdefRecord* record) {}
};
// Adds and removes observers for events on this NFC tag. If monitoring
// multiple tags, check the |tag| parameter of observer methods to determine
// which tag is issuing the event.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// NfcTagTechnology override.
bool IsSupportedByTag() const override;
// Returns all NDEF records that were received from the tag in the form of an
// NDEF message. If the returned NDEF message contains no records, this only
// means that no records have yet been received from the tag. Users should
// use this method in conjunction with the NfcTag::Observer::RecordsReceived
// method to be notified when the records are ready.
virtual const NfcNdefMessage& GetNdefMessage() const = 0;
// Writes the given NDEF message to the underlying tag, overwriting any
// existing NDEF message on it. On success, |callback| will be invoked. On
// failure, |error_callback| will be invoked. This method can fail, if the
// underlying tag does not support NDEF as a technology.
virtual void WriteNdef(const NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
protected:
// Constructs a technology instance, where |tag| is the NFC tag that this
// instance will operate on.
explicit NfcNdefTagTechnology(NfcTag* tag);
DISALLOW_COPY_AND_ASSIGN(NfcNdefTagTechnology);
};
} // namespace device
#endif // DEVICE_NFC_NFC_TAG_TECHNOLOGY_H_

@ -1,186 +0,0 @@
// Copyright 2014 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 "device/nfc/nfc_tag_technology_chromeos.h"
#include "base/stl_util.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "device/nfc/nfc_ndef_record_utils_chromeos.h"
#include "device/nfc/nfc_tag_chromeos.h"
using device::NfcNdefMessage;
using device::NfcNdefRecord;
namespace chromeos {
namespace {
typedef std::vector<dbus::ObjectPath> ObjectPathVector;
} // namespace
NfcNdefTagTechnologyChromeOS::NfcNdefTagTechnologyChromeOS(NfcTagChromeOS* tag)
: NfcNdefTagTechnology(tag),
object_path_(tag->object_path()),
weak_ptr_factory_(this) {
DCHECK(tag);
// Create record objects for all records that were received before.
const ObjectPathVector& records =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetRecordsForTag(object_path_);
for (ObjectPathVector::const_iterator iter = records.begin();
iter != records.end(); ++iter) {
AddRecord(*iter);
}
DBusThreadManager::Get()->GetNfcRecordClient()->AddObserver(this);
}
NfcNdefTagTechnologyChromeOS::~NfcNdefTagTechnologyChromeOS() {
DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this);
base::STLDeleteValues(&records_);
}
void NfcNdefTagTechnologyChromeOS::AddObserver(
NfcNdefTagTechnology::Observer* observer) {
observers_.AddObserver(observer);
}
void NfcNdefTagTechnologyChromeOS::RemoveObserver(
NfcNdefTagTechnology::Observer* observer) {
observers_.RemoveObserver(observer);
}
const NfcNdefMessage& NfcNdefTagTechnologyChromeOS::GetNdefMessage() const {
return message_;
}
void NfcNdefTagTechnologyChromeOS::WriteNdef(
const device::NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (message.records().empty()) {
LOG(ERROR) << "Given NDEF message is empty. Cannot write it.";
error_callback.Run();
return;
}
if (!tag()->IsReady()) {
LOG(ERROR) << "The tag is not ready yet: " << tag()->GetIdentifier();
error_callback.Run();
return;
}
// TODO(armansito): neard currently supports writing only one NDEF record
// to a tag and won't support multiple records until 0.15. Until then, report
// failure if |message| contains more than one record.
if (message.records().size() > 1) {
LOG(ERROR) << "Currently, writing only 1 NDEF record is supported.";
error_callback.Run();
return;
}
const NfcNdefRecord* record = message.records()[0];
base::DictionaryValue attributes;
if (!nfc_ndef_record_utils::NfcNdefRecordToDBusAttributes(
record, &attributes)) {
LOG(ERROR) << "Failed to extract NDEF record fields for NDEF push.";
error_callback.Run();
return;
}
DBusThreadManager::Get()->GetNfcTagClient()->Write(
object_path_,
attributes,
base::Bind(&NfcNdefTagTechnologyChromeOS::OnWriteNdefMessage,
weak_ptr_factory_.GetWeakPtr(), callback),
base::Bind(&NfcNdefTagTechnologyChromeOS::OnWriteNdefMessageError,
weak_ptr_factory_.GetWeakPtr(), error_callback));
}
void NfcNdefTagTechnologyChromeOS::RecordAdded(
const dbus::ObjectPath& object_path) {
// Don't create the record object yet. Instead, wait until all record
// properties have been received and construct the object and notify observers
// then.
VLOG(1) << "Record added: " << object_path.value() << ". Waiting until "
"all properties have been fetched to create record object.";
}
void NfcNdefTagTechnologyChromeOS::RecordRemoved(
const dbus::ObjectPath& object_path) {
NdefRecordMap::iterator iter = records_.find(object_path);
if (iter == records_.end())
return;
VLOG(1) << "Lost remote NDEF record object: " << object_path.value()
<< ", removing record.";
NfcNdefRecord* record = iter->second;
message_.RemoveRecord(record);
delete record;
records_.erase(iter);
}
void NfcNdefTagTechnologyChromeOS::RecordPropertiesReceived(
const dbus::ObjectPath& object_path) {
VLOG(1) << "Record properties received for: " << object_path.value();
// Check if the found record belongs to this tag.
bool record_found = false;
const ObjectPathVector& records =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetRecordsForTag(object_path_);
for (ObjectPathVector::const_iterator iter = records.begin();
iter != records.end(); ++iter) {
if (*iter == object_path) {
record_found = true;
break;
}
}
if (!record_found) {
VLOG(1) << "Record \"" << object_path.value() << "\" doesn't belong to this"
<< " tag. Ignoring.";
return;
}
AddRecord(object_path);
}
void NfcNdefTagTechnologyChromeOS::OnWriteNdefMessage(
const base::Closure& callback) {
callback.Run();
}
void NfcNdefTagTechnologyChromeOS::OnWriteNdefMessageError(
const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(ERROR) << object_path_.value() << ": Failed to Push NDEF message: "
<< error_name << ": " << error_message;
error_callback.Run();
}
void NfcNdefTagTechnologyChromeOS::AddRecord(
const dbus::ObjectPath& object_path) {
// Ignore this call if an entry for this record already exists.
if (records_.find(object_path) != records_.end()) {
VLOG(1) << "Record object for remote \"" << object_path.value()
<< "\" already exists.";
return;
}
NfcRecordClient::Properties* record_properties =
DBusThreadManager::Get()->GetNfcRecordClient()->
GetProperties(object_path);
DCHECK(record_properties);
NfcNdefRecord* record = new NfcNdefRecord();
if (!nfc_ndef_record_utils::RecordPropertiesToNfcNdefRecord(
record_properties, record)) {
LOG(ERROR) << "Failed to create record object for record with object "
<< "path \"" << object_path.value() << "\"";
delete record;
return;
}
message_.AddRecord(record);
records_[object_path] = record;
FOR_EACH_OBSERVER(NfcNdefTagTechnology::Observer, observers_,
RecordReceived(tag(), record));
}
} // namespace chromeos

@ -1,86 +0,0 @@
// Copyright 2014 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.
#ifndef DEVICE_NFC_NFC_TAG_TECHNOLOGY_CHROMEOS_H_
#define DEVICE_NFC_NFC_TAG_TECHNOLOGY_CHROMEOS_H_
#include <map>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chromeos/dbus/nfc_record_client.h"
#include "device/nfc/nfc_tag_technology.h"
namespace chromeos {
class NfcTagChromeOS;
// The NfcNdefTagTechnologyChromeOS class implements
// device::NfcNdefTagTechnology for the Chrome OS platform. The lifetime of an
// instance of this class must be tied to an instance of NfcTagChromeOS.
// Instances of this class must never outlast the owning NfcTagChromeOS
// instance.
class NfcNdefTagTechnologyChromeOS : public device::NfcNdefTagTechnology,
public NfcRecordClient::Observer {
public:
~NfcNdefTagTechnologyChromeOS() override;
// device::NfcNdefTagTechnology overrides.
void AddObserver(device::NfcNdefTagTechnology::Observer* observer) override;
void RemoveObserver(
device::NfcNdefTagTechnology::Observer* observer) override;
const device::NfcNdefMessage& GetNdefMessage() const override;
void WriteNdef(const device::NfcNdefMessage& message,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
// NfcRecordClient::Observer overrides.
void RecordAdded(const dbus::ObjectPath& object_path) override;
void RecordRemoved(const dbus::ObjectPath& object_path) override;
void RecordPropertiesReceived(const dbus::ObjectPath& object_path) override;
private:
friend class NfcTagChromeOS;
// Mapping from D-Bus object paths to NfcNdefRecord objects.
typedef std::map<dbus::ObjectPath, device::NfcNdefRecord*> NdefRecordMap;
explicit NfcNdefTagTechnologyChromeOS(NfcTagChromeOS* tag);
// Called by dbus:: on completion of the D-Bus method call to write an NDEF.
void OnWriteNdefMessage(const base::Closure& callback);
void OnWriteNdefMessageError(const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Creates a record object for the record with object path |object_path| and
// notifies the observers, if a record object did not already exist for it.
void AddRecord(const dbus::ObjectPath& object_path);
// A map containing the NDEF records that were received from the tag.
NdefRecordMap records_;
// Message instance that contains pointers to all created records that are
// in |records_|. This is mainly used as the cached return value for
// GetNdefMessage().
device::NfcNdefMessage message_;
// List of observers interested in event notifications from us.
base::ObserverList<device::NfcNdefTagTechnology::Observer> observers_;
// D-Bus object path of the remote tag or device that this object operates
// on.
dbus::ObjectPath object_path_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<NfcNdefTagTechnologyChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(NfcNdefTagTechnologyChromeOS);
};
} // namespace chromeos
#endif // DEVICE_NFC_NFC_TAG_TECHNOLOGY_CHROMEOS_H_