diff --git a/apps/settings/index.html b/apps/settings/index.html
index f831f2a4b067..a5e982e7f1e0 100644
--- a/apps/settings/index.html
+++ b/apps/settings/index.html
@@ -506,11 +506,7 @@
Device
-
- -
-
-
-
+
diff --git a/apps/settings/js/icc.js b/apps/settings/js/icc.js
index e56a1edf3e01..b88346a50b9c 100644
--- a/apps/settings/js/icc.js
+++ b/apps/settings/js/icc.js
@@ -4,6 +4,12 @@
'use strict';
(function() {
+ var iccManager = window.navigator.mozIccManager;
+ function getIcc(iccId) {
+ DUMP('ICC Getting ICC for ' + iccId);
+ return iccManager.getIccById(iccId);
+ }
+
var _ = navigator.mozL10n.get;
// Consts
@@ -14,12 +20,12 @@
/**
* Init
*/
- var iccMenuItem = document.getElementById('menuItem-icc');
var iccStkList = document.getElementById('icc-stk-list');
var iccStkHeader = document.getElementById('icc-stk-header');
var iccStkSubheader = document.getElementById('icc-stk-subheader');
- var iccLastCommand = null;
- var iccLastCommandProcessed = false;
+ var exitHelp = document.getElementById('icc-stk-help-exit');
+ var backButton = document.getElementById('icc-stk-app-back');
+ var exitButton = document.getElementById('icc-stk-exit');
var stkOpenAppName = null;
var stkLastSelectedTest = null;
var goBackTimer = {
@@ -30,70 +36,47 @@
timer: null,
timeout: 0
};
- var icc;
- var iccManager;
-
init();
/**
* Init STK UI
*/
function init() {
- // See bug 932134
- // To keep all tests passed while introducing multi-sim APIs, in bug 928325
- // we use IccHelper. Stop using IccHelper after the APIs land.
- if (!IccHelper) {
- return;
- }
- icc = IccHelper;
- iccManager = window.navigator.mozIccManager;
-
- icc.onstksessionend = function handleSTKSessionEnd(event) {
- updateMenu();
- Settings.currentPanel = '#icc';
- };
+ window.addEventListener('stkasynccommand',
+ function do_handleAsyncSTKCmd(event) {
+ handleSTKMessage(event.detail.message);
+ });
- document.getElementById('icc-stk-app-back').onclick = stkResGoBack;
- document.getElementById('icc-stk-help-exit').onclick = updateMenu;
+ window.addEventListener('stkmenuselection',
+ function do_handleAsyncSTKCmd(event) {
+ updateMenu(event.detail.menu);
+ });
+ }
- document.addEventListener('visibilitychange', function() {
+ function addCloseNotificationsEvents(message) {
+ function onVisibilityChange() {
if (document.hidden && Settings.currentPanel == '#icc') {
- stkResTerminate();
+ stkResTerminate(message);
}
- }, false);
+ }
+ document.removeEventListener('visibilitychange', onVisibilityChange, false);
+ document.addEventListener('visibilitychange', onVisibilityChange, false);
window.onbeforeunload = function() {
- responseSTKCommand({
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_NO_RESPONSE_FROM_USER
}, true);
};
-
- window.addEventListener('stkasynccommand',
- function do_handleAsyncSTKCmd(event) {
- handleSTKCommand(event.detail.command);
- });
-
- /**
- * Open STK main application
- */
- iccMenuItem.onclick = function onclick() {
- updateMenu();
- };
-
- // Load STK apps
- updateMenu();
}
- function stkResTerminate() {
+ function stkResTerminate(message) {
Settings.currentPanel = '#root';
- iccLastCommandProcessed = true;
- responseSTKCommand({
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_UICC_SESSION_TERM_BY_USER
}, true);
}
- function stkResGoBack() {
- iccLastCommandProcessed = true;
- responseSTKCommand({
+ function stkResGoBack(message) {
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_BACKWARD_MOVE_BY_USER
});
// We'll return to settings if no STK response received in a grace period
@@ -107,17 +90,16 @@
};
};
- function stkResNoResponse() {
+ function stkResNoResponse(message) {
var reqTimerSelect =
window.navigator.mozSettings.createLock().get('icc.selectTimeout');
reqTimerSelect.onsuccess = function icc_getTimerSelectSuccess() {
selectTimer.timeout = reqTimerSelect.result['icc.selectTimeout'];
selectTimer.timer = setTimeout(function() {
- iccLastCommandProcessed = true;
- responseSTKCommand({
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_NO_RESPONSE_FROM_USER
}, true);
- stkResGoBack();
+ stkResGoBack(message);
}, selectTimer.timeout);
};
};
@@ -137,54 +119,41 @@
* Updates the STK header buttons
*/
function setSTKScreenType(type) {
- var exit = document.getElementById('icc-stk-exit');
- var back = document.getElementById('icc-stk-app-back');
- var helpExit = document.getElementById('icc-stk-help-exit');
-
switch (type) {
case STK_SCREEN_MAINMENU:
- exit.classList.remove('hidden');
- back.classList.add('hidden');
- helpExit.classList.add('hidden');
+ exitButton.classList.remove('hidden');
+ backButton.classList.add('hidden');
+ exitHelp.classList.add('hidden');
break;
case STK_SCREEN_HELP:
- exit.classList.add('hidden');
- back.classList.add('hidden');
- helpExit.classList.remove('hidden');
+ exitButton.classList.add('hidden');
+ backButton.classList.add('hidden');
+ exitHelp.classList.remove('hidden');
break;
default: // STK_SCREEN_DEFAULT
- exit.classList.add('hidden');
- back.classList.remove('hidden');
- helpExit.classList.add('hidden');
+ exitButton.classList.add('hidden');
+ backButton.classList.remove('hidden');
+ exitHelp.classList.add('hidden');
}
}
/**
* Response ICC Command
*/
- function responseSTKCommand(response, force) {
- if (!force && (!iccLastCommand || !iccLastCommandProcessed)) {
- DUMP('sendStkResponse NO COMMAND TO RESPONSE. Ignoring');
- return;
- }
-
- DUMP('sendStkResponse to command: ', iccLastCommand);
+ function responseSTKCommand(message, response) {
+ DUMP('sendStkResponse to message: ', message);
DUMP('sendStkResponse -- # response = ', response);
- icc.sendStkResponse(iccLastCommand, response);
- iccLastCommand = null;
- iccLastCommandProcessed = false;
+ getIcc(message.iccId).sendStkResponse(message.command, response);
}
/**
- * Handle ICC Commands
+ * Handle ICC Messages
*/
- function handleSTKCommand(command) {
- DUMP('STK Proactive Command:', command);
- iccLastCommand = command;
- var options = command.options;
+ function handleSTKMessage(message) {
+ DUMP('STK Proactive Message:', message);
stkCancelGoBack();
@@ -193,17 +162,19 @@
reopenSettings();
- switch (command.typeOfCommand) {
+ switch (message.command.typeOfCommand) {
case iccManager.STK_CMD_SELECT_ITEM:
- updateSelection(command);
- openSTKApplication();
- iccLastCommandProcessed = true;
+ addCloseNotificationsEvents(message);
+ updateSelection(message);
+ Settings.currentPanel = '#icc';
+ backButton.onclick = function _back() {
+ stkResGoBack(message);
+ };
break;
default:
DUMP('STK Message not managed... response OK');
- iccLastCommandProcessed = true;
- responseSTKCommand({
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_OK
});
}
@@ -212,99 +183,101 @@
/**
* Navigate through all available STK applications
*/
- function updateMenu() {
- DUMP('Showing STK main menu');
+ function updateMenu(menu) {
+ DUMP('Showing STK main menu: ', menu);
stkOpenAppName = null;
stkCancelGoBack();
- var reqApplications =
- window.navigator.mozSettings.createLock().get('icc.applications');
- reqApplications.onsuccess = function icc_getApplications() {
- var json = reqApplications.result['icc.applications'];
- var menu = json && JSON.parse(json);
- clearList();
-
- setSTKScreenType(STK_SCREEN_MAINMENU);
-
- if (!menu || !menu.items ||
- (menu.items.length == 1 && menu.items[0] === null)) {
- DUMP('No STK available - hide & exit');
- document.getElementById('icc-mainheader').hidden = true;
- document.getElementById('icc-mainentry').hidden = true;
- return;
- }
+ clearList();
+ setSTKScreenType(STK_SCREEN_MAINMENU);
- DUMP('STK Main App Menu title: ' + menu.title);
- DUMP('STK Main App Menu default item: ' + menu.defaultItem);
-
- iccMenuItem.textContent = menu.title;
- showTitle(menu.title);
- menu.items.forEach(function(menuItem) {
- DUMP('STK Main App Menu item: ' + menuItem.text + ' # ' +
- menuItem.identifier);
- iccStkList.appendChild(buildMenuEntry({
- id: 'stk-menuitem-' + menuItem.identifier,
- text: menuItem.text,
- nai: _(menuItem.nai),
- onclick: onMainMenuItemClick,
- attributes: [['stk-menu-item-identifier', menuItem.identifier]]
- }));
- });
+ if (!menu || !menu.entries || !menu.entries.items ||
+ (menu.entries.items.length == 1 && menu.entries.items[0] === null)) {
+ return;
+ }
- // Optional Help menu
- if (menu.isHelpAvailable) {
- iccStkList.appendChild(buildMenuEntry({
- id: 'stk-helpmenuitem',
- text: _('operatorServices-helpmenu'),
- onclick: showHelpMenu,
- attributes: []
- }));
- }
- };
+ DUMP('STK Main App Menu title: ' + menu.entries.title);
+ DUMP('STK Main App Menu default item: ' + menu.entries.defaultItem);
+
+ showTitle(menu.entries.title);
+ menu.entries.items.forEach(function(menuItem) {
+ DUMP('STK Main App Menu item: ' + menuItem.text + ' # ' +
+ menuItem.identifier);
+ iccStkList.appendChild(buildMenuEntry({
+ id: 'stk-menuitem-' + menuItem.identifier,
+ text: menuItem.text,
+ nai: _(menuItem.nai),
+ onclick: onMainMenuItemClick,
+ attributes: [
+ ['stk-menu-item-identifier', menuItem.identifier],
+ ['stk-menu-item-iccId', menu.iccId]
+ ]
+ }));
+ });
- stkResNoResponse();
+ // Optional Help menu
+ if (menu.entries.isHelpAvailable) {
+ iccStkList.appendChild(buildMenuEntry({
+ id: 'stk-helpmenuitem',
+ text: _('operatorServices-helpmenu'),
+ onclick: function __onHelpClick__(event) {
+ showHelpMenu(menu, event);
+ },
+ attributes: []
+ }));
+ }
+
+ getIcc(menu.iccId).onstksessionend = function handleSTKSessionEnd(event) {
+ updateMenu(menu);
+ Settings.currentPanel = '#icc';
+ };
}
function onMainMenuItemClick(event) {
+ var iccId = event.target.getAttribute('stk-menu-item-iccId');
var identifier = event.target.getAttribute('stk-menu-item-identifier');
DUMP('sendStkMenuSelection: ', identifier);
- icc.sendStkMenuSelection(identifier, false);
+
+ getIcc(iccId).sendStkMenuSelection(identifier, false);
stkLastSelectedTest = event.target.textContent;
stkOpenAppName = stkLastSelectedTest;
}
- function showHelpMenu(event) {
+ function showHelpMenu(menu, event) {
DUMP('Showing STK help menu');
stkOpenAppName = null;
- var reqApplications =
- window.navigator.mozSettings.createLock().get('icc.applications');
- reqApplications.onsuccess = function icc_getApplications() {
- var menu = JSON.parse(reqApplications.result['icc.applications']);
- clearList();
-
- setSTKScreenType(STK_SCREEN_HELP);
-
- iccMenuItem.textContent = menu.title;
- showTitle(_('operatorServices-helpmenu'));
- menu.items.forEach(function(menuItem) {
- DUMP('STK Main App Help item: ' + menuItem.text + ' # ' +
- menuItem.identifier);
- iccStkList.appendChild(buildMenuEntry({
- id: 'stk-helpitem-' + menuItem.identifier,
- text: menuItem.text,
- onclick: onMainMenuHelpItemClick,
- attributes: [['stk-help-item-identifier', menuItem.identifier]]
- }));
- });
+ clearList();
+
+ setSTKScreenType(STK_SCREEN_HELP);
+
+ showTitle(_('operatorServices-helpmenu'));
+ menu.entries.items.forEach(function(menuItem) {
+ DUMP('STK Main App Help item: ' + menuItem.text + ' # ' +
+ menuItem.identifier);
+ iccStkList.appendChild(buildMenuEntry({
+ id: 'stk-helpitem-' + menuItem.identifier,
+ text: menuItem.text,
+ onclick: onMainMenuHelpItemClick,
+ attributes: [
+ ['stk-help-item-identifier', menuItem.identifier],
+ ['stk-menu-item-iccId', menu.iccId]
+ ]
+ }));
+ });
+
+ exitHelp.onclick = function _closeHelp() {
+ updateMenu(menu);
};
}
function onMainMenuHelpItemClick(event) {
+ var iccId = event.target.getAttribute('stk-menu-item-iccId');
var identifier = event.target.getAttribute('stk-help-item-identifier');
DUMP('sendStkHelpMenuSelection: ', identifier);
- icc.sendStkMenuSelection(identifier, true);
+
+ getIcc(iccId).sendStkMenuSelection(identifier, true);
stkLastSelectedTest = event.target.textContent;
stkOpenAppName = stkLastSelectedTest;
}
@@ -312,8 +285,8 @@
/**
* Navigate through the STK application options
*/
- function updateSelection(command) {
- var menu = command.options;
+ function updateSelection(message) {
+ var menu = message.command.options;
DUMP('Showing STK menu');
clearList();
@@ -329,17 +302,19 @@
id: 'stk-menuitem-' + menuItem.identifier,
text: menuItem.text,
nai: _(menuItem.nai),
- onclick: onSelectOptionClick.bind(null, command),
+ onclick: function onSelectOptionClick(event) {
+ onSelectOption(message, event);
+ },
attributes: [['stk-select-option-identifier', menuItem.identifier]]
}));
});
- stkResNoResponse();
+ stkResNoResponse(message);
}
- function onSelectOptionClick(command, event) {
+ function onSelectOption(message, event) {
var identifier = event.target.getAttribute('stk-select-option-identifier');
- responseSTKCommand({
+ responseSTKCommand(message, {
resultCode: iccManager.STK_RESULT_OK,
itemIdentifier: identifier
});
@@ -393,15 +368,8 @@
li.appendChild(a);
return li;
}
-
- /**
- * Open settings application with ICC section opened
- */
- function openSTKApplication() {
- Settings.currentPanel = '#icc';
- window.navigator.mozApps.getSelf().onsuccess = function getSelfCB(evt) {
- var app = evt.target.result;
- app.launch('settings');
- };
- };
})();
+
+window.dispatchEvent(new CustomEvent('iccPageLoaded', {
+ detail: {}
+}));
diff --git a/apps/settings/js/icc_menu.js b/apps/settings/js/icc_menu.js
index 0a572e4c265f..f997b0a982d9 100644
--- a/apps/settings/js/icc_menu.js
+++ b/apps/settings/js/icc_menu.js
@@ -4,9 +4,27 @@
'use strict';
(function() {
- function executeICCCmd(iccCommand) {
- if (!iccCommand)
+ var iccMainHeader = document.getElementById('icc-mainheader');
+ var iccEntries = document.getElementById('icc-entries');
+
+ var iccLoaded = false;
+ function loadIccPage(callback) {
+ callback = (typeof callback === 'function') ? callback : function() {};
+ if (iccLoaded) {
+ return callback();
+ }
+ Settings.currentPanel = '#icc';
+ window.addEventListener('iccPageLoaded',
+ function oniccPageLoaded(event) {
+ iccLoaded = true;
+ callback();
+ });
+ }
+
+ function executeICCCmd(iccMessage) {
+ if (!iccMessage) {
return;
+ }
// Clear cache
var reqIccData = window.navigator.mozSettings.createLock().set({
@@ -17,15 +35,13 @@
};
// Open ICC section
- DUMP('ICC command to execute: ', iccCommand);
- Settings.currentPanel = '#icc';
-
- setTimeout(function() {
+ DUMP('ICC message to execute: ', iccMessage);
+ loadIccPage(function() {
var event = new CustomEvent('stkasynccommand', {
- detail: { 'command': iccCommand }
+ detail: { 'message': iccMessage }
});
window.dispatchEvent(event);
- }, 2000);
+ });
}
setTimeout(function updateStkMenu() {
@@ -35,20 +51,53 @@
var settings = Settings.mozSettings;
var lock = settings.createLock();
- function showStkEntry(menu) {
- if (!menu || !menu.items ||
- (menu.items.length == 1 && menu.items[0] === null)) {
+ function showStkEntries(menu) {
+ DUMP('STK cached menu: ', menu);
+ if (!menu || typeof menu !== 'object' || Object.keys(menu).length == 0) {
DUMP('No STK available - exit');
- document.getElementById('icc-mainheader').hidden = true;
- document.getElementById('icc-mainentry').hidden = true;
+ iccMainHeader.hidden = true;
+ iccEntries.hidden = true;
return;
}
+ // Clean current entries
+ iccEntries.innerHTML = '';
+ iccMainHeader.hidden = true;
+ iccEntries.hidden = true;
+
// update and show the entry in settings
- DUMP('STK Main App Menu title: ' + menu.title);
- document.getElementById('menuItem-icc').textContent = menu.title;
- document.getElementById('icc-mainheader').hidden = false;
- document.getElementById('icc-mainentry').hidden = false;
+ Object.keys(menu).forEach(function(SIMNumber) {
+ DUMP('STK Menu for SIM ' + SIMNumber +
+ ' (' + menu[SIMNumber].iccId + ') - ', menu[SIMNumber].entries);
+
+ var li = document.createElement('li');
+ var small = document.createElement('small');
+ // XXX this line requires a better l10n support, see bug 968853
+ small.textContent = 'SIM ' + SIMNumber;
+ small.classList.add('menu-item-desc');
+ li.appendChild(small);
+ var a = document.createElement('a');
+ a.textContent = menu[SIMNumber].entries.title;
+ a.id = 'menuItem-icc-' + menu[SIMNumber].iccId;
+ a.classList.add('menu-item');
+ a.classList.add('menuItem-icc');
+ a.href = '#icc';
+ a.onclick = function menu_icc_onclick() {
+ DUMP('Touched ' + menu[SIMNumber].iccId);
+ loadIccPage(function() {
+ var event = new CustomEvent('stkmenuselection', {
+ detail: { 'menu': menu[SIMNumber] }
+ });
+ window.dispatchEvent(event);
+ });
+ };
+ li.appendChild(a);
+
+ iccEntries.appendChild(li);
+
+ iccMainHeader.hidden = false;
+ iccEntries.hidden = false;
+ });
}
// Check if SIM card sends an Applications menu
@@ -56,14 +105,14 @@
reqApplications.onsuccess = function icc_getApplications() {
var json = reqApplications.result['icc.applications'];
var menu = json && JSON.parse(json);
- showStkEntry(menu);
+ showStkEntries(menu);
};
settings.addObserver('icc.applications',
function icc_getApplications(event) {
var json = event.settingValue;
var menu = json && JSON.parse(json);
- showStkEntry(menu);
+ showStkEntries(menu);
});
// Check if there are pending STK commands
@@ -85,4 +134,3 @@
});
});
})();
-
diff --git a/apps/settings/style/icons.css b/apps/settings/style/icons.css
index 8ca01ba9e293..47272272ed81 100644
--- a/apps/settings/style/icons.css
+++ b/apps/settings/style/icons.css
@@ -153,7 +153,7 @@ li:active:not([aria-disabled="true"]) .menu-item::before,
background-position: -9rem -12rem;
}
-#menuItem-icc::before {
+.menuItem-icc::before {
background-position: -12rem -12rem;
}
diff --git a/apps/system/js/icc.js b/apps/system/js/icc.js
index 26b0e0fe40b9..b811b25be700 100644
--- a/apps/system/js/icc.js
+++ b/apps/system/js/icc.js
@@ -11,9 +11,6 @@ var icc = {
init: function icc_init() {
this._iccManager = window.navigator.mozIccManager;
- this.hideViews();
- this.protectForms();
- this.getIccInfo();
var self = this;
this.clearMenuCache(function() {
window.navigator.mozSetMessageHandler('icc-stkcommand',
@@ -24,6 +21,10 @@ var icc = {
});
});
+ this.hideViews();
+ this.protectForms();
+ this.getIccInfo();
+
var self = this;
// Update displayTextTimeout with settings parameter
var reqDisplayTimeout = window.navigator.mozSettings.createLock().get(
@@ -144,8 +145,8 @@ var icc = {
*/
responseSTKCommand: function icc_responseSTKCommand(message, response) {
DUMP('STK sendStkResponse -- # response = ', response);
-
- (icc.getIcc(message.iccId)).sendStkResponse(message.command, response);
+ var _icc = icc.getIcc(message.iccId);
+ _icc && _icc.sendStkResponse(message.command, response);
},
/**
diff --git a/apps/system/js/icc_worker.js b/apps/system/js/icc_worker.js
index a58ac14f9102..2b08dbf3501d 100644
--- a/apps/system/js/icc_worker.js
+++ b/apps/system/js/icc_worker.js
@@ -4,6 +4,10 @@
'use strict';
var icc_worker = {
+ // STK Applications menu list. On bootup this object is empty,
+ // will be filled by 0x25 (STK_CMD_SET_UP_MENU) command.
+ iccApplicationsMenu: {},
+
dummy: function icc_worker_dummy(message) {
DUMP('STK Command not implemented yet');
icc.responseSTKCommand(message, {
@@ -302,7 +306,7 @@ var icc_worker = {
DUMP('STK_CMD_SET_UP_MENU. Transferring to ' + application + ': ',
message.command);
var reqIccData = window.navigator.mozSettings.createLock().set({
- 'icc.data': JSON.stringify(message.command)
+ 'icc.data': JSON.stringify(message)
});
reqIccData.onsuccess = function icc_getIccData() {
if (AppWindowManager.getRunningApps()[application]) {
@@ -323,11 +327,21 @@ var icc_worker = {
// STK_CMD_SET_UP_MENU
'0x25': function STK_CMD_SET_UP_MENU(message) {
DUMP('STK_CMD_SET_UP_MENU:', message.command.options);
- var reqApplications = window.navigator.mozSettings.createLock().set({
- 'icc.applications': JSON.stringify(message.command.options)
+ var settings = window.navigator.mozSettings;
+
+ // With test/fake commands: No SIM detected; we set it as SIM 0
+ this.iccApplicationsMenu[icc.getSIMNumber(message.iccId) || 0] = {
+ iccId: message.iccId,
+ entries: message.command.options
+ };
+
+ // Update this.iccApplicationsMenu cache
+ var reqApplications = settings.createLock().set({
+ 'icc.applications': JSON.stringify(this.iccApplicationsMenu)
});
+ var self = this;
reqApplications.onsuccess = function icc_getApplications() {
- DUMP('Cached');
+ DUMP('STK: Cached - ', self.iccApplicationsMenu);
icc.responseSTKCommand(message, {
resultCode: icc._iccManager.STK_RESULT_OK
});