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 #19137 from KevinGrandon/bug_971506_system2_intern…
Browse files Browse the repository at this point in the history
…et_sharing

Bug 971506 - [System2] Instantiable InternetSharing
  • Loading branch information
KevinGrandon committed May 17, 2014
2 parents 3afc852 + d3f77d5 commit d364c47
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 134 deletions.
5 changes: 4 additions & 1 deletion apps/system/js/bootstrap.js
Expand Up @@ -9,7 +9,8 @@
TelephonySettings, SuspendingAppPriorityManager, TTLView,
MediaRecording, AppWindowFactory, SystemDialogManager,
applications, Rocketbar, LayoutManager, PermissionManager,
HomeSearchbar, SoftwareButtonManager, Accessibility */
HomeSearchbar, SoftwareButtonManager, Accessibility,
InternetSharing */

'use strict';

Expand Down Expand Up @@ -105,6 +106,8 @@ window.addEventListener('load', function startup() {
window.dialerAgent = new DialerAgent().start();
window.homeGesture = new HomeGesture().start();
window.homeSearchbar = new HomeSearchbar();
window.internetSharing = new InternetSharing();
window.internetSharing.start();
window.layoutManager = new LayoutManager().start();
window.permissionManager = new PermissionManager();
window.permissionManager.start();
Expand Down
266 changes: 153 additions & 113 deletions apps/system/js/internet_sharing.js
@@ -1,22 +1,13 @@
/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';
/* global asyncStorage */
/* global IccHelper */
/* global ModalDialog */

/*
* Internet Sharing module responsible for saving and restoring the internet
* sharing state, including Wifi hotspot and USB tethering, based on sim card.
*
* The sharing state is linked with sim card id, iccid. When a user changes sim
* card, this module restore the last state of that sim card.
*
* If the there is no sim card or sim card is not ready, this module use the
* settings of no sim card in which Wifi hotspot will always be disabled.
*/

var InternetSharing = (function() {
(function(exports) {

// Local reference to mozSettings
var settings;

// null or unknown state will change to one of the following state
var validCardState = [null,
'pinRequired',
Expand All @@ -31,112 +22,161 @@ var InternetSharing = (function() {
'ruimServiceProviderLocked',
'ready'];

var observerHooked = false;
/**
* Internet Sharing module responsible for saving and restoring the internet
* sharing state, including Wifi hotspot and USB tethering, based on sim card.
*
* The sharing state is linked with sim card id, iccid. When a user changes
* sim card, this module restore the last state of that sim card.
*
* If the there is no sim card or sim card is not ready, this module use the
* settings of no sim card in which Wifi hotspot will always be disabled.
* @requires asyncStorage
* @requires IccHelper
* @requires ModalDialog
* @class InternetSharing
*/
function InternetSharing() {}

var cardState;
InternetSharing.prototype = {

function addObservers() {
if (observerHooked) {
return;
}
observerHooked = true;
// listen changes after value is restored.
['usb', 'wifi'].forEach(function(type) {
settings.addObserver('tethering.' + type + '.enabled',
internetSharingSettingsChangeHanlder);
});
}
/**
* Whether or not we have added settings observers.
* @type {Boolean}
* @memberof InternetSharing.prototype
*/
_observerHooked: false,

function checkCardAndInternetSharing() {
cardState = IccHelper.cardState;
if (validCardState.indexOf(cardState) > -1) {
// if it is known cardState, we need to load internet sharing state from
// settings
addObservers();
restoreInternetSharingState(cardState);
}
}
/**
* Current sim card state.
* @type {String}
* @memberof InternetSharing.prototype
*/
_cardState: null,

function restoreInternetSharingState(cardState) {
// the function restores settings based on type, cardId.
function doRestore(type, cardId, forceDisabled) {
// build the key for asyncStorage.
var key = 'tethering.' + type + '.simstate.card-' + cardId;
asyncStorage.getItem(key, function callback(value) {
// if forceDisable is true, we need to disable it always.
var simState = forceDisabled ? false : (value || false);
// update value for type
var cset = {};
cset['tethering.' + type + '.enabled'] = simState;
settings.createLock().set(cset);
});
}
// the internet sharing is linked with iccid, if cardState is not ready, we
// just view it as no sim.
// note if it is under pinRequired or pukRequired, it may turned into ready
// state after user typed pin or puk.
if (cardState === 'ready') {
// once cardState is ready, we need to read iccid
// if iccInfo.iccid is not ready, we need to listen change of iccinfo
// change, until iccid is ready
if (!IccHelper.iccInfo || !IccHelper.iccInfo.iccid) {
IccHelper.oniccinfochange = function handler() {
// wait for iccid is filled.
if (IccHelper.iccInfo && IccHelper.iccInfo.iccid) {
IccHelper.oniccinfochange = null;
doRestore('usb', IccHelper.iccInfo.iccid);
doRestore('wifi', IccHelper.iccInfo.iccid);
}
};
/**
* Adds observers for when the usb or wifi setting is changed.
* @memberof InternetSharing.prototype
*/
addObservers: function() {
if (this._observerHooked) {
return;
}
this._observerHooked = true;
// listen changes after value is restored.
['usb', 'wifi'].forEach(function(type) {
settings.addObserver('tethering.' + type + '.enabled',
this.internetSharingSettingsChangeHanlder.bind(this));
}, this);
},

/**
* If it is known cardState, we need to load internet sharing state from
* settings.
* @memberof InternetSharing.prototype
*/
checkCardAndInternetSharing: function() {
this._cardState = IccHelper.cardState;
if (validCardState.indexOf(this._cardState) > -1) {
this.addObservers();
this.restoreInternetSharingState();
}
},

/**
* Restores the state of internet sharing.
* Grabs the state from asyncStorage and saves it to mozSettings.
* @memberof InternetSharing.prototype
*/
restoreInternetSharingState: function() {
// the function restores settings based on type, cardId.
function doRestore(type, cardId, forceDisabled) {
// build the key for asyncStorage.
var key = 'tethering.' + type + '.simstate.card-' + cardId;
asyncStorage.getItem(key, function callback(value) {
// if forceDisable is true, we need to disable it always.
var simState = forceDisabled ? false : (value || false);
// update value for type
var cset = {};
cset['tethering.' + type + '.enabled'] = simState;
settings.createLock().set(cset);
});
}
// the internet sharing is linked with iccid, if cardState is not ready,
// we just view it as no sim.
// note if it is under pinRequired or pukRequired, it may turned into
// ready state after user typed pin or puk.
if (this._cardState === 'ready') {
// once cardState is ready, we need to read iccid
// if iccInfo.iccid is not ready, we need to listen change of iccinfo
// change, until iccid is ready
if (!IccHelper.iccInfo || !IccHelper.iccInfo.iccid) {
IccHelper.oniccinfochange = function handler() {
// wait for iccid is filled.
if (IccHelper.iccInfo && IccHelper.iccInfo.iccid) {
IccHelper.oniccinfochange = null;
doRestore('usb', IccHelper.iccInfo.iccid);
doRestore('wifi', IccHelper.iccInfo.iccid);
}
};
} else {
// iccInfo is ready, just use it.
doRestore('usb', IccHelper.iccInfo.iccid);
doRestore('wifi', IccHelper.iccInfo.iccid);
}
} else {
// iccInfo is ready, just use it.
doRestore('usb', IccHelper.iccInfo.iccid);
doRestore('wifi', IccHelper.iccInfo.iccid);
// card is not ready, just use absent to restore the value.
doRestore('usb', 'absent');
// card is not ready, force wifi hotspot disabled.
doRestore('wifi', 'absent', true);
}
} else {
// card is not ready, just use absent to restore the value.
doRestore('usb', 'absent');
// card is not ready, force wifi hotspot disabled.
doRestore('wifi', 'absent', true);
}
}
},

function internetSharingSettingsChangeHanlder(evt) {
var _ = navigator.mozL10n.get;
if (validCardState.indexOf(cardState) === -1) {
return;
}
// link the iccid with current internet state for future restoring.
var type = (evt.settingName.indexOf('wifi') > -1) ? 'wifi' : 'usb';
var cardId = (IccHelper.iccInfo && IccHelper.iccInfo.iccid) || 'absent';
// wifi hotspot cannot be enabled without sim
if ('wifi' === type && 'absent' === cardId && true === evt.settingValue) {
var title = _('noSimCard');
var buttonText = _('ok');
var message = _('noSIMCardInHotspot');
/**
* Called whenever there is a setting change in usb or wifi tethering.
* Validates that we can turn internet sharing on, and saves state to
* asyncStorage.
* @memberof InternetSharing.prototype
*/
internetSharingSettingsChangeHanlder: function(evt) {
var _ = navigator.mozL10n.get;
if (validCardState.indexOf(this._cardState) === -1) {
return;
}
// link the iccid with current internet state for future restoring.
var type = (evt.settingName.indexOf('wifi') > -1) ? 'wifi' : 'usb';
var cardId = (IccHelper.iccInfo && IccHelper.iccInfo.iccid) || 'absent';
// wifi hotspot cannot be enabled without sim
if ('wifi' === type && 'absent' === cardId && true === evt.settingValue) {
var title = _('noSimCard');
var buttonText = _('ok');
var message = _('noSIMCardInHotspot');

ModalDialog.alert(title, message, { title: buttonText });
settings.createLock().set({'tethering.wifi.enabled': false});
return;
}
asyncStorage.setItem('tethering.' + type + '.simstate.card-' + cardId,
evt.settingValue);
}
ModalDialog.alert(title, message, { title: buttonText });
settings.createLock().set({'tethering.wifi.enabled': false});
return;
}
asyncStorage.setItem('tethering.' + type + '.simstate.card-' + cardId,
evt.settingValue);
},

function _init() {
settings = window.navigator.mozSettings;
if (!settings) {
return;
}
if (!IccHelper) {
return;
/**
* Starts the InternetSharing class.
* @memberof InternetSharing.prototype
*/
start: function() {
settings = window.navigator.mozSettings;
if (!IccHelper) {
return;
}
this._observerHooked = false;
this.checkCardAndInternetSharing();
// listen cardstatechange event for ready, pin, puk, or network unlocking.
IccHelper.addEventListener('cardstatechange',
this.checkCardAndInternetSharing.bind(this));
}
observerHooked = false;
checkCardAndInternetSharing();
// listen cardstatechange event for ready, pin, puk, or network unlocking.
IccHelper.addEventListener('cardstatechange', checkCardAndInternetSharing);
}
return {init: _init};
})();
};

exports.InternetSharing = InternetSharing;

InternetSharing.init();
}(window));
6 changes: 5 additions & 1 deletion apps/system/test/unit/bootstrap_test.js
Expand Up @@ -2,7 +2,8 @@
/*global MockNavigatormozApps, MockNavigatorSettings, MocksHelper, MockL10n*/
/*global MockApplications, Applications*/

requireApp('system/shared/js/screen_layout.js');
requireApp('system/shared/js/async_storage.js');
requireApp('system/shared/test/unit/mocks/mock_icc_helper.js');
requireApp('system/shared/test/unit/mocks/mock_navigator_moz_apps.js');
requireApp('system/shared/test/unit/mocks/mock_navigator_moz_settings.js');
requireApp('system/shared/test/unit/mocks/mock_settings_listener.js');
Expand All @@ -20,6 +21,7 @@ requireApp('system/js/rocketbar.js');
requireApp('system/js/home_gesture.js');
requireApp('system/js/home_searchbar.js');
requireApp('system/js/homescreen_launcher.js');
requireApp('system/js/internet_sharing.js');
requireApp('system/js/layout_manager.js');
requireApp('system/js/lockscreen_window_manager.js');
requireApp('system/js/media_recording.js');
Expand Down Expand Up @@ -54,6 +56,7 @@ mocha.globals([
'homeGesture',
'homeSearchbar',
'homescreenLauncher',
'internetSharing',
'layoutManager',
'lockScreenWindowManager',
'mediaRecording',
Expand All @@ -76,6 +79,7 @@ mocha.globals([

var mocksForBootstrap = new MocksHelper([
'Applications',
'IccHelper',
'ScreenManager',
'Places',
'SettingsListener',
Expand Down

0 comments on commit d364c47

Please sign in to comment.