Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
344
gaia/apps/system/js/eu_roaming_manager.js
Executable file
344
gaia/apps/system/js/eu_roaming_manager.js
Executable file
|
|
@ -0,0 +1,344 @@
|
|||
/* globals SIMSlotManager, Notification, NotificationHelper, MozActivity,
|
||||
Promise, LazyLoader, BaseModule */
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var EU_ROAMING_FILE_PATH = '/resources/eu-roaming.json';
|
||||
|
||||
/**
|
||||
* EuRoamingManager observes the mobile codes of the current connected
|
||||
* operator and display a notification when necessary.
|
||||
*
|
||||
* @class EuRoamingManager
|
||||
*/
|
||||
function EuRoamingManager(core) {
|
||||
this._connections = Array.slice(core.mobileConnections || []);
|
||||
|
||||
this._simMobileCodes = [];
|
||||
this._curNetworkMobileCodes = [];
|
||||
|
||||
this._homeOperatorList = null;
|
||||
this._foreignOperatorList = null;
|
||||
}
|
||||
|
||||
BaseModule.create(EuRoamingManager, {
|
||||
name: 'EuRoamingManager',
|
||||
TAG_PREFIX: 'euRoamingNotificaton',
|
||||
EU_ROAMING_ENABLED_KEY: 'eu-roaming.enabled',
|
||||
EU_ROAMING_NOTIFICATION_STATE_KEY: 'eu-roaming.notification.state',
|
||||
NOTIFICATION_STATES: {
|
||||
UNAVAILABLE: 'unavailable',
|
||||
DISPLAYED: 'displayed',
|
||||
OPENED: 'opened'
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the module.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
*/
|
||||
_start: function() {
|
||||
// Clear existing notifications.
|
||||
this._clearNotifications();
|
||||
this._init();
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the EU roaming file and register related listeners when necessary.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_init: function() {
|
||||
var that = this;
|
||||
|
||||
return this._loadJSON(EU_ROAMING_FILE_PATH)
|
||||
.then(function(result) {
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
that._homeOperatorList = result.home;
|
||||
that._foreignOperatorList = result.foreign;
|
||||
|
||||
if (that._homeOperatorList &&
|
||||
that._foreignOperatorList &&
|
||||
Object.keys(that._homeOperatorList).length > 0 &&
|
||||
Object.keys(that._foreignOperatorList).length > 0) {
|
||||
that._initValues();
|
||||
that._addSimChangeListener();
|
||||
that._addDataChangeListener();
|
||||
|
||||
// Check the current state ar first.
|
||||
that._connections.forEach(
|
||||
that._tryShowEuRoamingNotification.bind(that));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialzes values.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
*/
|
||||
_initValues: function() {
|
||||
// Initialize the default values.
|
||||
SIMSlotManager.getSlots().forEach(function(simSlot, index) {
|
||||
this._curNetworkMobileCodes.push(null);
|
||||
|
||||
var iccInfo = simSlot && simSlot.simCard && simSlot.simCard.iccInfo;
|
||||
if (iccInfo) {
|
||||
this._simMobileCodes.push({ mcc: iccInfo.mcc, mnc: iccInfo.mnc });
|
||||
} else {
|
||||
this._simMobileCodes.push(null);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the mobile codes is a valid EU romaing home operator.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @param {String} mcc
|
||||
* @param {String} mnc
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
_isEURoamingHomeOperator: function(mcc, mnc) {
|
||||
if (!this._homeOperatorList || !mcc || !mnc) {
|
||||
return false;
|
||||
}
|
||||
return !!this._homeOperatorList[mcc][mnc];
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the mobile codes is a valid EU romaing foreign operator.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @param {String} mcc
|
||||
* @param {String} mnc
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
_isEURoamingForeignOperator: function(mcc, mnc) {
|
||||
if (!this._foreignOperatorList || !mcc || !mnc) {
|
||||
return false;
|
||||
}
|
||||
return !!this._foreignOperatorList[mcc][mnc];
|
||||
},
|
||||
|
||||
/**
|
||||
* Add listeners on events related to the change of the mobile codes stored
|
||||
* on the icc card.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
*/
|
||||
_addSimChangeListener: function() {
|
||||
['updated', 'iccinfochange', 'cardstatechange'].forEach(
|
||||
function(eventName) {
|
||||
window.addEventListener('simslot-' + eventName,
|
||||
this._onSimChanged.bind(this));
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add listeners on events related to the change of the mobile codes of the
|
||||
* currently connected data network.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
*/
|
||||
_addDataChangeListener: function() {
|
||||
this._connections.forEach(function(connection, index) {
|
||||
connection.addEventListener('datachange', function() {
|
||||
this._tryShowEuRoamingNotification(connection, index);
|
||||
}.bind(this));
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* The function stores the mobile codes of the currently used sim card and
|
||||
* try to display the notification.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
*/
|
||||
_onSimChanged: function(event) {
|
||||
var simSlot = event.detail;
|
||||
var iccInfo = simSlot && simSlot.simCard && simSlot.simCard.iccInfo;
|
||||
|
||||
if (!iccInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._simMobileCodes[simSlot.index] =
|
||||
{ mcc: iccInfo.mcc, mnc: iccInfo.mnc };
|
||||
this._tryShowEuRoamingNotification(simSlot.conn, simSlot.index);
|
||||
},
|
||||
|
||||
/**
|
||||
* The function displays the EU roaming notification when:
|
||||
* - Roaming on the newly connected data network.
|
||||
* - The mobile codes of the operators of the sim card are listed in the
|
||||
* "home" section of the EU roaming file.
|
||||
* - The mobile codes of the operators of the connected data network are
|
||||
* listed in the "foreign" section of the EU roaming file.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @param {MobileConnection} connection
|
||||
* @param {Number} index
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_tryShowEuRoamingNotification: function(connection, index) {
|
||||
var data = connection.data;
|
||||
var network = data && data.network;
|
||||
if (!network) {
|
||||
return;
|
||||
}
|
||||
|
||||
var simMobileCode = this._simMobileCodes[index];
|
||||
var simMcc = simMobileCode && simMobileCode.mcc;
|
||||
var simMnc = simMobileCode && simMobileCode.mnc;
|
||||
|
||||
var curNetworkMobileCode = this._curNetworkMobileCodes[index];
|
||||
var curNetworkMcc = curNetworkMobileCode && curNetworkMobileCode.mcc;
|
||||
var curNetworkMnc = curNetworkMobileCode && curNetworkMobileCode.mnc;
|
||||
|
||||
if (network.mcc !== curNetworkMcc || network.mnc !== curNetworkMnc) {
|
||||
// a new operator detected.
|
||||
this._curNetworkMobileCodes[index] =
|
||||
{ mcc: network.mcc, mnc: network.mnc };
|
||||
|
||||
if (data.roaming &&
|
||||
// check if the operator of the sim is in the EU regulation list.
|
||||
this._isEURoamingHomeOperator(simMcc, simMnc) &&
|
||||
// check if the new operator is a supported foreign operator or not.
|
||||
this._isEURoamingForeignOperator(network.mcc, network.mnc)) {
|
||||
return this._getState(this.EU_ROAMING_NOTIFICATION_STATE_KEY + index)
|
||||
.then(function(notificationState) {
|
||||
this._setState(this.EU_ROAMING_ENABLED_KEY + index, true);
|
||||
// display the notification if it has never been opened before.
|
||||
if (notificationState !== this.NOTIFICATION_STATES.OPENED) {
|
||||
this._showNotification(index);
|
||||
return this._setState(
|
||||
this.EU_ROAMING_NOTIFICATION_STATE_KEY + index,
|
||||
this.NOTIFICATION_STATES.DISPLAYED);
|
||||
}
|
||||
}.bind(this)).catch(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
} else {
|
||||
return Promise.all([
|
||||
this._setState(this.EU_ROAMING_ENABLED_KEY + index, false),
|
||||
this._setState(this.EU_ROAMING_NOTIFICATION_STATE_KEY + index,
|
||||
this.NOTIFICATION_STATES.UNAVAILABLE)
|
||||
]).catch(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all notifications of EU roaming.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_clearNotifications: function() {
|
||||
var that = this;
|
||||
return Notification.get().then(function(notifications) {
|
||||
notifications.forEach(function(notification) {
|
||||
var tag = notification && notification.tag;
|
||||
if (!tag || !tag.startsWith(that.TAG_PREFIX)) {
|
||||
return;
|
||||
}
|
||||
notification.close();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the EU roaming notification of a sim card.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @param {Number} serviceId
|
||||
*/
|
||||
_showNotification: function(serviceId) {
|
||||
var iconUrl = window.location.origin + '/style/eu_roaming_manager/' +
|
||||
'eu_roaming.png';
|
||||
var options = {
|
||||
bodyL10n: 'euRoamingNotificationMsg',
|
||||
icon: iconUrl,
|
||||
tag: this.TAG_PREFIX + serviceId,
|
||||
mozbehavior: {
|
||||
showOnlyOnce: true
|
||||
}
|
||||
};
|
||||
return NotificationHelper.send('euRoamingNotificationTitle',
|
||||
options).then(
|
||||
notification => {
|
||||
notification.onclick = function() {
|
||||
this._triggerSettingsActivity(serviceId);
|
||||
}.bind(this);
|
||||
|
||||
notification.onclose = function() {
|
||||
this._setState(this.EU_ROAMING_NOTIFICATION_STATE_KEY + serviceId,
|
||||
this.NOTIFICATION_STATES.OPENED);
|
||||
};
|
||||
return notification;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Invokes an activity for setting the EU roaming apn.
|
||||
*
|
||||
* @memberof EuRoamingManager.prototype
|
||||
* @param {Number} serviceId
|
||||
*/
|
||||
_triggerSettingsActivity: function(serviceId) {
|
||||
var activity = new MozActivity({
|
||||
name: 'configure',
|
||||
data: {
|
||||
target: 'device',
|
||||
section: 'apn-list',
|
||||
options: {
|
||||
role: 'activity',
|
||||
type: 'default',
|
||||
serviceId: serviceId
|
||||
}
|
||||
}
|
||||
});
|
||||
activity.onsuccess = function() {};
|
||||
},
|
||||
|
||||
_getState: function(key) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var req = navigator.mozSettings.createLock().get(key);
|
||||
req.onsuccess = function() {
|
||||
resolve(req.result[key]);
|
||||
};
|
||||
req.onerror = function() {
|
||||
reject('get state ' + key + ' error');
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
_setState: function(key, state) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var obj = {};
|
||||
obj[key] = state;
|
||||
var req = navigator.mozSettings.createLock().set(obj);
|
||||
req.onsuccess = resolve;
|
||||
req.onerror = function() {
|
||||
reject('set state ' + key + ' error');
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
_loadJSON: function(path) {
|
||||
return LazyLoader.getJSON(path).then(function(json) {
|
||||
return Promise.resolve(json);
|
||||
}, function(error) {
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
}
|
||||
});
|
||||
}());
|
||||
Loading…
Reference in a new issue