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 #30504 from crh0716/1172155
Browse files Browse the repository at this point in the history
Bug 1172155 - Show a warning when switching to UMS on devices with a limited support r=eragonj
  • Loading branch information
crh0716 committed Jun 15, 2015
2 parents 02ff3f5 + 361614f commit 5a06fc6
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 79 deletions.
17 changes: 17 additions & 0 deletions apps/settings/elements/partial_ums_warning.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<element name="partial-ums-warning" extends="section">
<template>
<gaia-confirm>
<h1 data-l10n-id="ums-partial-support-warning-title"></h1>
<p>
<span data-l10n-id="ums-partial-support-warning-msg-1"></span>
<br/>
<br/>
<span data-l10n-id="ums-partial-support-warning-msg-2"></span>
</p>
<gaia-buttons skin="dark">
<button type="reset" data-l10n-id="cancel"></button>
<button type="submit" data-l10n-id="ok"></button>
</gaia-buttons>
</gaia-confirm>
</template>
</element>
3 changes: 3 additions & 0 deletions apps/settings/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@
<link rel="import" href="/elements/frame.html">
<link rel="import" href="/elements/full_developer_mode.html">
<link rel="import" href="/elements/full_developer_mode_final_warning.html">
<link rel="import" href="/elements/partial_ums_warning.html">
<link rel="import" href="/elements/templates/messaging.html">
<link rel="import" href="/elements/root.html">
<link rel="import" href="/elements/settings_alert_dialog.html">
Expand Down Expand Up @@ -431,6 +432,8 @@
<section is="full-developer-mode" role="region" id="full-developer-mode"></section>
<!-- Full Developer Mode Final Warning -->
<section is="full-developer-mode-final-warning" role="region" id="full-developer-mode-final-warning" class="dialog"></section>
<!-- Parital Ums Warning -->
<section is="partial-ums-warning" role="region" id="partial-ums-warning" class="dialog"></section>
<!-- SettingsDialog :: AlertDialog -->
<section is="settings-alert-dialog" class="dialog" role="region" id="settings-alert-dialog"></section>
<!-- SettingsDialog :: ConFirmDialog -->
Expand Down
59 changes: 33 additions & 26 deletions apps/settings/js/modules/panel_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,35 +382,42 @@ define(function(require) {
}

// update <input> values when the corresponding setting is changed
var input = panel.querySelector(`input[name="${key}"],
gaia-switch[name="${key}"]`);
if (!input) {
var inputs = [].slice.call(panel.querySelectorAll(`input[name="${key}"],
gaia-switch[name="${key}"]`));
if (!inputs.length) {
return;
}
switch (input.type) {
case 'gaia-switch':
case 'checkbox':
case 'switch':
if (input.checked == value) {
return;
}
input.checked = value;
break;
case 'range':
if (input.value == value) {
return;
}
input.value = value;
break;
case 'select':
for (i = 0, count = input.options.length; i < count; i++) {
if (input.options[i].value == value) {
input.options[i].selected = true;
break;

inputs.forEach((input) => {
switch (input.type) {
case 'gaia-switch':
case 'checkbox':
case 'switch':
value = !!value;
if (input.checked === value) {
return;
}
}
break;
}
input.checked = value;
break;
case 'range':
if (input.value === value) {
return;
}
input.value = value;
break;
case 'select':
for (i = 0, count = input.options.length; i < count; i++) {
if (input.options[i].value === value) {
input.options[i].selected = true;
break;
}
}
break;
case 'radio':
input.checked = (input.value === value);
break;
}
});
},

/**
Expand Down
20 changes: 19 additions & 1 deletion apps/settings/js/panels/usb_storage/usb_transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ define(function(require) {

var SettingsCache = require('modules/settings_cache');
var SettingsListener = require('shared/settings_listener');
var DialogService = require('modules/dialog_service');

var UsbTransfer = function() {
this._keyUmsEnabled = 'ums.enabled';
this._keyUmsMode = 'ums.mode';
this._keyTransferProtocol = 'usb.transfer';

this._partialUmsSupport = !navigator.getDeviceStorages('sdcard').every(
storage => storage.canBeShared);

this.PROTOCOL_UMS = '0';
this.PROTOCOL_MTP = '1';

Expand Down Expand Up @@ -59,16 +63,30 @@ define(function(require) {
* @memberOf UsbTransfer.prototype
* @param {Number} mode current mode
* @param {Number} protocol transfer protocol
* @return {Promise}
*/
_changeMode: function ut_changeMode(mode, protocol) {
if (mode !== this.MODE_MTP && protocol === this.PROTOCOL_MTP) {
this._setMode(this.MODE_MTP);
} else if (mode === this.MODE_MTP &&
protocol === this.PROTOCOL_UMS) {
this._setMode(this.MODE_UMS);
if (this._partialUmsSupport) {
return DialogService.show('partial-ums-warning').then((result) => {
if (result.type === 'cancel') {
var param = {};
param[this._keyTransferProtocol] = this.PROTOCOL_MTP;
SettingsListener.getSettingsLock().set(param);
} else {
this._setMode(this.MODE_UMS);
}
});
} else {
this._setMode(this.MODE_UMS);
}
} else {
console.log('Error: should not be executed');
}
return Promise.resolve();
},

/**
Expand Down
3 changes: 3 additions & 0 deletions apps/settings/locales/settings.en-US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,9 @@ format-sdcard-internal-title=Format internal storage
format-sdcard-internal-message=This will erase all data stored on your internal storage, such as music and photos.
format-sdcard-btnformat=Format
sdcardUnmounted=SD card unmounted
ums-partial-support-warning-title=Warning: USB Mass Storage may not work
ums-partial-support-warning-msg-1=USB Mass Storage will only work correctly with an external SD card. If you'd like to be able to access both your internal and external storage, you must use MTP.
ums-partial-support-warning-msg-2=Press "OK" to switch to USB Mass Storage, or "Cancel" to remain in MTP mode.

#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#=#
# Device
Expand Down
153 changes: 101 additions & 52 deletions apps/settings/test/unit/panels/usb_storage/usb_transfer_test.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,72 @@
/* global MockNavigatorSettings*/
'use strict';

requireApp('settings/shared/test/unit/mocks/mock_navigator_moz_settings.js');

suite('start testing > ', function() {
var realMozSettings;
var realSettingsListener;
var mockSettingsCache;
var usbTransfer;
var realGetDeviceStorages;

var _keyTransferProtocol = 'usb.transfer';
var MockSettingsListener;
var MockDialogService;
var usbTransfer;

var MODE_UMS = 1;
var MODE_UMS_UNPLUG = 2;
var MODE_MTP = 3;
var PROTOCOL_UMS = '0';
var PROTOCOL_MTP = '1';

suiteSetup(function(done) {
testRequire([
'shared_mocks/mock_settings_listener',
'unit/mock_settings_cache',
'panels/usb_storage/usb_transfer'
],
{ //mock map
'*': {
'module/settings_cache': 'unit/mock_settings_cache',
'shared/settings_listener': 'shared_mocks/mock_settings_listener'
}
},
function(MockSettingsListener, MockSettingsCache, usb_transfer) {
realMozSettings = window.navigator.mozSettings;
window.navigator.mozSettings = MockNavigatorSettings;

realSettingsListener = window.SettingsListener;
window.SettingsListener = MockSettingsListener;

mockSettingsCache = MockSettingsCache;
var modules = [
'panels/usb_storage/usb_transfer'
];
var map = { //mock map
'*': {
'modules/settings_cache': 'unit/mock_settings_cache',
'shared/settings_listener': 'MockSettingsListener',
'modules/dialog_service': 'MockDialogService'
}
};

setup(function(done) {
var requireCtx = testRequire([], map, function() {});

MockDialogService = {
show: function() {}
};
define('MockDialogService', function() {
return MockDialogService;
});

MockSettingsListener = {
observe: function() {},
getSettingsLock: function() {}
};
define('MockSettingsListener', function() {
return MockSettingsListener;
});

requireCtx(modules, function(usb_transfer) {
realGetDeviceStorages = window.navigator.getDeviceStorages;
window.navigator.getDeviceStorages = sinon.stub().returns([{
canBeShared: true
}]);

usbTransfer = usb_transfer();
done();
});
});

suiteTeardown(function() {
window.navigator.mozSettings = realMozSettings;
window.SettingsListener = realSettingsListener;
teardown(function() {
window.navigator.getDeviceStorages = realGetDeviceStorages;
});

suite('initialization', function() {
setup(function() {
this.sinon.stub(usbTransfer, '_configProtocol');
this.sinon.stub(MockSettingsListener, 'observe');
usbTransfer.init();
});

test('init', function() {
window.SettingsListener.mTriggerCallback(_keyTransferProtocol,
PROTOCOL_UMS);
assert.ok(usbTransfer._configProtocol.called);
MockSettingsListener.observe.args[0][2].call(usbTransfer, 'fakeProtocol');
assert.ok(usbTransfer._configProtocol.calledWith('fakeProtocol'));
});
});

Expand All @@ -67,34 +76,74 @@ suite('start testing > ', function() {
this.sinon.stub(usbTransfer, '_setMode');
});

test('mode 1 + protocol ums', function() {
usbTransfer._changeMode(MODE_UMS, PROTOCOL_UMS);
assert.ok(!usbTransfer._setMode.called);
test('mode 1 + protocol ums', function(done) {
usbTransfer._changeMode(MODE_UMS, PROTOCOL_UMS).then(() => {
assert.ok(!usbTransfer._setMode.called);
}).then(done, done);
});

test('mode 2 + protocol ums', function(done) {
usbTransfer._changeMode(MODE_UMS_UNPLUG, PROTOCOL_UMS).then(() => {
assert.ok(!usbTransfer._setMode.called);
}).then(done, done);
});

test('mode 2 + protocol ums', function() {
usbTransfer._changeMode(MODE_UMS_UNPLUG, PROTOCOL_UMS);
assert.ok(!usbTransfer._setMode.called);
test('mode 3 + protocol ums', function(done) {
usbTransfer._changeMode(MODE_MTP, PROTOCOL_UMS).then(() => {
assert.ok(usbTransfer._setMode.calledWith(MODE_UMS));
}).then(done, done);
});

test('mode 3 + protocol ums', function() {
usbTransfer._changeMode(MODE_MTP, PROTOCOL_UMS);
assert.ok(usbTransfer._setMode.calledWith(MODE_UMS));
test('mode 1 + protocol mtp', function(done) {
usbTransfer._changeMode(MODE_UMS, PROTOCOL_MTP).then(() => {
assert.ok(usbTransfer._setMode.calledWith(MODE_MTP));
}).then(done, done);
});

test('mode 1 + protocol mtp', function() {
usbTransfer._changeMode(MODE_UMS, PROTOCOL_MTP);
assert.ok(usbTransfer._setMode.calledWith(MODE_MTP));
test('mode 2 + protocol mtp', function(done) {
usbTransfer._changeMode(MODE_UMS_UNPLUG, PROTOCOL_MTP).then(() => {
assert.ok(usbTransfer._setMode.calledWith(MODE_MTP));
}).then(done, done);
});

test('mode 2 + protocol mtp', function() {
usbTransfer._changeMode(MODE_UMS_UNPLUG, PROTOCOL_MTP);
assert.ok(usbTransfer._setMode.calledWith(MODE_MTP));
test('mode 3 + protocol mtp', function(done) {
usbTransfer._changeMode(MODE_MTP, PROTOCOL_MTP).then(() => {
assert.ok(!usbTransfer._setMode.called);
}).then(done, done);
});

test('mode 3 + protocol mtp', function() {
usbTransfer._changeMode(MODE_MTP, PROTOCOL_MTP);
assert.ok(!usbTransfer._setMode.called);
suite('mode 3 + protocol ums + partial ums support', function() {
setup(function() {
usbTransfer._partialUmsSupport = true;
});

test('should rollback to mtp when the user cancel it', function(done) {
var mockLock = {
set: sinon.stub()
};
this.sinon.stub(MockSettingsListener,
'getSettingsLock').returns(mockLock);

this.sinon.stub(MockDialogService, 'show').returns(Promise.resolve({
type: 'cancel'
}));
usbTransfer._changeMode(MODE_MTP, PROTOCOL_UMS).then(() => {
assert.ok(MockDialogService.show.called);
assert.deepEqual(mockLock.set.args[0][0], {
'usb.transfer': PROTOCOL_MTP
});
}).then(done, done);
});

test('should set to ums correctly when the user confirms',
function(done) {
this.sinon.stub(MockDialogService, 'show').returns(Promise.resolve({
type: 'submit'
}));
usbTransfer._changeMode(MODE_MTP, PROTOCOL_UMS).then(() => {
assert.ok(usbTransfer._setMode.calledWith(MODE_UMS));
}).then(done, done);
});
});
});
});

0 comments on commit 5a06fc6

Please sign in to comment.