Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #28083 from svic/Bug_1120849_v2.2
Browse files Browse the repository at this point in the history
Bug 1120849 - Don't allow concurrent file transfers
  • Loading branch information
rvandermeulen committed Mar 17, 2015
2 parents d0e09d5 + 3e9dabe commit c48d20c
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 5 deletions.
5 changes: 5 additions & 0 deletions apps/system/js/bluetooth_transfer.js
Expand Up @@ -301,6 +301,11 @@ var BluetoothTransfer = {
return this._sendingFilesQueue.length === 0;
},

get isFileTransferInProgress() {
var jobs = this.transferStatusList.querySelector('div');
return jobs != null;
},

sendFileViaHandover: function bt_sendFileViaHandover(mac, blob) {
var adapter = Bluetooth.getAdapter();
if (adapter != null) {
Expand Down
12 changes: 12 additions & 0 deletions apps/system/js/ndef_utils.js
Expand Up @@ -419,5 +419,17 @@ var NDEFUtils = {
payload: new Uint8Array(OOB)})];

return hs;
},

/**
* Returns an empty Handover Select NDEF message (i.e., a Hs message with no
* AC).
* @returns {Array} NDEF records for an empty handover select message.
*/
encodeEmptyHandoverSelect: function encodeEmptyHandoverSelect() {
var hs = [new MozNDEFRecord({tnf: NDEF.TNF_WELL_KNOWN,
type: NDEF.RTD_HANDOVER_SELECT,
payload: new Uint8Array([0x12])})];
return hs;
}
};
41 changes: 37 additions & 4 deletions apps/system/js/nfc_handover_manager.js
Expand Up @@ -320,18 +320,27 @@ var NfcHandoverManager = {

/**
* Show an error notification when file transfer failed.
* @param {String} name Optional file name.
* @param {String} msg Optional message.
* @memberof NfcHandoverManager.prototype
*/
_showFailedNotification: function _showFailedNotification(title, name) {
var fileName = (name !== undefined) ? name : '';
_showFailedNotification: function _showFailedNotification(title, msg) {
var body = (msg !== undefined) ? msg : '';
var icon = 'style/bluetooth_transfer/images/icon_bluetooth.png';
NotificationHelper.send(title, {
body: fileName,
body: body,
icon: icon
});
},

/**
* Show 'send failed, try again' notification.
*/
_showTryAgainNotification: function _showTryAgainNotification() {
var _ = navigator.mozL10n.get;
this._showFailedNotification('transferFinished-sentFailed-title',
_('transferFinished-try-again-description'));
},

/**
* This function will be called after a timeout when we did not receive the
* Hs record within three seconds. At this point we cancel the file transfer.
Expand Down Expand Up @@ -583,6 +592,15 @@ var NfcHandoverManager = {
this._clearTimeout();
var btssp = this._getBluetoothSSP(ndef);
if (btssp == null) {
if (this.sendFileQueue.length !== 0) {
// We tried to send a file but the other device gave us an empty AC
// record. This will happen if the other device is currently
// transferring a file. Show a 'try later' notification.
this._debug('Other device is transferring file. Aborting');
var job = this.sendFileQueue.shift();
job.onerror();
this._showTryAgainNotification();
}
return;
}
if (this.sendFileQueue.length !== 0) {
Expand All @@ -602,6 +620,14 @@ var NfcHandoverManager = {
*/
_handleHandoverRequest: function _handleHandoverRequest(ndef, nfcPeer) {
this._debug('_handleHandoverRequest');
if (BluetoothTransfer.isFileTransferInProgress) {
// We don't allow concurrent file transfers
this._debug('This device is currently transferring a file. ' +
'Aborting via empty Hs');
var hs = NDEFUtils.encodeEmptyHandoverSelect();
nfcPeer.sendNDEF(hs);
return;
}
this._saveBluetoothStatus();
this._doAction({callback: this._doHandoverRequest, args: [ndef, nfcPeer]});
},
Expand Down Expand Up @@ -649,6 +675,13 @@ var NfcHandoverManager = {
*/
handleFileTransfer: function handleFileTransfer(nfcPeer, blob, requestId) {
this._debug('handleFileTransfer');
if (BluetoothTransfer.isFileTransferInProgress) {
// We don't allow concurrent file transfers
this._debug('This device is already transferring a file. Aborting');
this._dispatchSendFileStatus(1, requestId);
this._showTryAgainNotification();
return;
}
this._saveBluetoothStatus();
this._doAction({callback: this._initiateFileTransfer, args: [nfcPeer, blob,
requestId]});
Expand Down
1 change: 1 addition & 0 deletions apps/system/locales/system.en-US.properties
Expand Up @@ -361,6 +361,7 @@ transferFinished-sentSuccessful-title=File sent
transferFinished-receivedSuccessful-title=File received
transferFinished-sentFailed-title=File could not be sent
transferFinished-receivedFailed-title=File could not be received
transferFinished-try-again-description=Cannot send file right now. Please try again later.
transferReport-title=Transfer report:
transferReport-description={{numSuccessful}} files successful, {{numUnsuccessful}} files unsuccessful
unknown-file=Unknown file
Expand Down
5 changes: 5 additions & 0 deletions apps/system/test/unit/mock_bluetooth_transfer.js
Expand Up @@ -7,6 +7,7 @@

var MockBluetoothTransfer = {
sendFileQueueEmpty: true,
fileTransferInProgress: false,
sendFileViaHandover: function(mac, blob) {
var req = new MockDOMRequest();
var details = {received: false,
Expand All @@ -22,6 +23,10 @@

get isSendFileQueueEmpty() {
return MockBluetoothTransfer.sendFileQueueEmpty;
},

get isFileTransferInProgress() {
return MockBluetoothTransfer.fileTransferInProgress;
}
};

Expand Down
34 changes: 33 additions & 1 deletion apps/system/test/unit/nfc_handover_manager_test.js
Expand Up @@ -231,7 +231,7 @@ suite('Nfc Handover Manager Functions', function() {

setup(function() {
MockBluetooth.enabled = true;

MockBluetoothTransfer.fileTransferInProgress = false;
spySendNDEF = this.sinon.spy(MockMozNfc.MockNFCPeer, 'sendNDEF');

fileRequest = {
Expand Down Expand Up @@ -278,6 +278,18 @@ suite('Nfc Handover Manager Functions', function() {
assert.equal(1, NfcHandoverManager.sendFileQueue.length);
});

test('Sending aborts when another file is transmitted concurrently',
function() {

MockBluetoothTransfer.fileTransferInProgress = true;
var stubShowNotification = this.sinon.stub(NfcHandoverManager,
'_showTryAgainNotification');
MockNavigatormozSetMessageHandler.mTrigger(
'nfc-manager-send-file', fileRequest);
assert.isTrue(stubShowNotification.calledOnce,
'Notification not shown');
});

test('Aborts when sendNDEF() fails.', function() {
MockNavigatormozSetMessageHandler.mTrigger(
'nfc-manager-send-file', fileRequest);
Expand Down Expand Up @@ -352,6 +364,26 @@ suite('Nfc Handover Manager Functions', function() {

assert.isTrue(fileRequest.onsuccess.calledOnce);
});

test('Empty Handover Select results in abort',
function() {

fileRequest.onerror = sinon.stub();
NfcHandoverManager.sendFileQueue.push(fileRequest);

var stubShowNotification = this.sinon.stub(NfcHandoverManager,
'_showTryAgainNotification');
var spySendFile = this.sinon.spy(MockBluetoothTransfer,
'sendFileViaHandover');

var select = NDEFUtils.encodeEmptyHandoverSelect();
NfcHandoverManager._handleHandoverSelect(select);

assert.isTrue(spySendFile.notCalled);
assert.isTrue(fileRequest.onerror.calledOnce);
assert.isTrue(stubShowNotification.calledOnce,
'Notification not shown');
});
});

suite('Action queuing when Bluetooth disabled', function() {
Expand Down

0 comments on commit c48d20c

Please sign in to comment.