VulpesOS/gaia/apps/ftu/js/sim_manager.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

840 lines
27 KiB
JavaScript
Executable file

/* global ConfirmDialog,
MobileOperator,
Navigation,
SimContactsImporter,
UIManager,
utils */
'use strict';
var SimManager = (function() {
/*
* Icc helper object to track FTE related SIM state
*/
function Icc(mozIcc) {
this.mozIcc = mozIcc;
}
Icc.prototype = {
skipped: false,
unlocked: false,
alreadyImported: false,
mozIcc: null,
isLocked: function() {
return !this.unlocked && lockStates.indexOf(this.mozIcc.cardState) !== -1;
}
};
/*
* Update ui element with a retry count message for the given sim
*/
function showRetryCount(icc, lockType, uiElement) {
var request = icc.mozIcc.getCardLockRetryCount(lockType);
request.onsuccess = function() {
var retryCount = request.result.retryCount;
if (retryCount) {
var l10nArgs = {n: retryCount};
document.l10n.setAttributes(uiElement,'inputCodeRetriesLeft',
l10nArgs);
uiElement.classList.remove('hidden');
}
};
request.onerror = function() {
console.error('Could not fetch CardLockRetryCount', request.error.name);
};
}
// mozIcc.cardState values for a locked SIM
var lockStates = ['pinRequired', 'pukRequired', 'networkLocked',
'corporateLocked', 'serviceProviderLocked', 'network1Locked',
'network2Locked', 'hrpdNetworkLocked', 'ruimCorporateLocked',
'ruimServiceProviderLocked'];
return {
icc0: null,
icc1: null,
simSlots: window.navigator.mozMobileConnections ?
window.navigator.mozMobileConnections.length : 0,
// track the SIM that is currently being unlocked
_unlockingIcc: null,
init: function sm_init() {
this.mobConn = window.navigator.mozMobileConnections;
if (!this.mobConn) {
return;
}
this.iccManager = window.navigator.mozIccManager;
if (!this.iccManager) {
return;
}
// keep track of sim card info in slot 0 and 1
this.icc0 = null;
this.icc1 = null;
if (this.iccManager.iccIds[0]) {
this.updateIccState(this.iccManager.iccIds[0]);
}
if (this.iccManager.iccIds[1]) {
this.updateIccState(this.iccManager.iccIds[1]);
}
this.iccManager.addEventListener('iccdetected',
this.handleIccState.bind(this));
this.alreadyImported = false;
},
handleUnlockError: function sm_handleUnlockError(lockType, retryCount) {
var l10nArgs = {n: retryCount};
switch (lockType) {
case 'pin':
if (retryCount === 0) {
this.showPukScreen(this._unlockingIcc);
break;
}
UIManager.pinInput.value = '';
UIManager.pinInput.classList.add('onerror');
UIManager.pinError.classList.remove('hidden');
document.l10n.setAttributes(UIManager.pinRetriesLeft,
'inputCodeRetriesLeft', l10nArgs);
UIManager.pinRetriesLeft.classList.remove('hidden');
if (retryCount === 1) {
UIManager.pinError.
querySelector('.lastchance').classList.remove('hidden');
} else {
document.l10n.setAttributes(
UIManager.pinError.querySelector('.main'),
'pinAttemptMsg2',
l10nArgs
);
UIManager.pinError.querySelector('.main').classList.remove('hidden');
}
break;
case 'puk':
UIManager.pukInput.value = '';
UIManager.pukInput.classList.add('onerror');
UIManager.pukError.classList.remove('hidden');
UIManager.pukInfo.classList.add('hidden');
document.l10n.setAttributes(UIManager.pukRetriesLeft,
'inputCodeRetriesLeft', l10nArgs);
UIManager.pukRetriesLeft.classList.remove('hidden');
if (retryCount === 1) {
UIManager.pukError.
querySelector('.lastchance').classList.remove('hidden');
} else {
document.l10n.setAttributes(
UIManager.pukError.querySelector('.main'),
'pukAttemptMsg2',
l10nArgs
);
UIManager.pukError.querySelector('.main').classList.remove('hidden');
}
// TODO what if counter gets to 0 ??
break;
case 'nck':
case 'cck':
case 'spck':
UIManager.xckInput.value = '';
UIManager.xckInput.classList.add('onerror');
UIManager.xckError.classList.remove('hidden');
document.l10n.setAttributes(UIManager.xckRetriesLeft,
'inputCodeRetriesLeft', l10nArgs);
UIManager.xckRetriesLeft.classList.remove('hidden');
if (retryCount == 1) {
UIManager.xckError.
querySelector('.lastchance').classList.remove('hidden');
} else {
document.l10n.setAttributes(
UIManager.xckError.querySelector('.main'),
'nckAttemptMsg2',
l10nArgs
);
UIManager.xckError.querySelector('.main').classList.remove('hidden');
}
break;
}
},
available: function sm_available() {
var icc = this.guessIcc();
return (icc && icc.cardState === 'ready');
},
handleIccState: function sm_handleIccState(event) {
this.updateIccState(event.iccId);
},
updateIccState: function(iccId) {
var iccInfo = this.iccManager.getIccById(iccId);
if (!iccInfo) {
throw new Error('Unrecognized iccID: ' + iccId);
}
// determine SIM slot number
if (this.mobConn[0] && iccId === this.mobConn[0].iccId) {
this.icc0 = new Icc(iccInfo);
} else if (this.mobConn[1] && iccId === this.mobConn[1].iccId) {
this.icc1 = new Icc(iccInfo);
} else {
console.warn('ICC detected in unsupported slot', iccId);
}
},
/*
* Possible values:
* null,
* 'unknown',
* 'pinRequired',
* 'pukRequired',
* 'networkLocked',
* 'corporateLocked',
* 'serviceProviderLocked',
* 'network1Locked',
* 'network2Locked',
* 'hrpdNetworkLocked',
* 'ruimCorporateLocked',
* 'ruimServiceProviderLocked'
* 'ready'.
*/
handleCardState: function sm_handleCardState(callback, skipUnlockScreen) {
// used to track which SIM's PIN unlock
// screen we are currently displaying
this._unlockingIcc = null;
SimManager.checkSIMButton();
if (typeof callback === 'function') {
this.finishCallback = callback;
}
if (this.shouldShowUnlockScreen(this.icc0) && !skipUnlockScreen) {
this.showUnlockScreen(this.icc0);
} else if (this.shouldShowUnlockScreen(this.icc1) && !skipUnlockScreen) {
this.showUnlockScreen(this.icc1);
} else if (this.shouldShowSIMInfoScreen()) {
// reset skipped states so if we navigate back
// we will redisplay the SIM unlock screens
this.resetSkipped();
this.showSIMInfoScreen();
} else {
this.resetSkipped();
this.finish();
}
},
finish: function() {
this.hideScreen();
this.hideSIMInfoScreen();
// card state has been handled, so return
// to normal navigation, and only show cell
// data step if we have an unlocked sim
var showCellData = (this.icc0 && !this.icc0.isLocked()) ||
(this.icc1 && !this.icc1.isLocked());
this.finishCallback && this.finishCallback(showCellData);
},
shouldShowUnlockScreen: function sm_shouldShowLockScreen(icc) {
return icc && !icc.skipped && icc.isLocked();
},
// only show sim info screen if we have two SIMs inserted
shouldShowSIMInfoScreen: function sm_shouldShowSIMInfoScreen() {
return (this.icc0 && this.icc1);
},
showUnlockScreen: function sm_showUnlockScreen(icc) {
if (icc.unlocked) {
return;
}
this._unlockingIcc = icc;
switch (icc.mozIcc.cardState) {
case 'pinRequired':
this.showPinScreen(icc);
break;
case 'pukRequired':
this.showPukScreen(icc);
break;
case 'networkLocked':
case 'corporateLocked':
case 'serviceProviderLocked':
case 'network1Locked':
case 'network2Locked':
case 'hrpdNetworkLocked':
case 'ruimCorporateLocked':
case 'ruimServiceProviderLocked':
this.showXckScreen(icc);
break;
default:
throw new Error('Cannot show SIM unlock screen, unknown cardState ' +
icc.mozIcc.cardState);
}
},
/**
* A container of event listeners to avoid listening several times to the same
* event/object pair.
*/
voiceChangeListeners: [],
updateSIMInfoText: function sm_updateSIMInfoText(icc) {
var iccNumber = (icc === this.icc0) ? 1 : 2;
if (icc && icc.isLocked()) {
UIManager['simInfo' + iccNumber].classList.add('locked');
UIManager['simCarrier' + iccNumber].setAttribute('data-l10n-id',
'simPinLocked');
UIManager['simNumber' + iccNumber].removeAttribute('data-l10n-id');
UIManager['simNumber' + iccNumber].textContent = '';
} else {
UIManager['simInfo' + iccNumber].classList.remove('locked');
var mobConn = this.mobConn[iccNumber - 1];
var operator = MobileOperator
.userFacingInfo(mobConn)
.operator;
if (!operator && !this.voiceChangeListeners[iccNumber - 1]) {
// The operator is not yet populated, let's listen to the `voicechange`
// event once and update the UI later.
this.voiceChangeListeners[iccNumber - 1] = function(evt) {
var operator = MobileOperator
.userFacingInfo(mobConn)
.operator;
if (operator) {
// If we have an operator, we update the UI and stop listening.
UIManager['simCarrier' + iccNumber].removeAttribute('data-l10n-id');
UIManager['simCarrier' + iccNumber].textContent = operator;
mobConn.removeEventListener(
'voicechange', this.voiceChangeListeners[iccNumber - 1]);
this.voiceChangeListeners[iccNumber - 1] = null;
}
}.bind(this);
mobConn.addEventListener(
'voicechange', this.voiceChangeListeners[iccNumber - 1]);
}
if (operator) {
UIManager['simCarrier' + iccNumber].removeAttribute('data-l10n-id');
UIManager['simCarrier' + iccNumber].textContent = operator;
} else {
UIManager['simCarrier' + iccNumber].setAttribute(
'data-l10n-id', 'searchingOperator'
);
}
var number = icc.mozIcc.iccInfo.msisdn ||
icc.mozIcc.iccInfo.mdn || '';
if (number) {
UIManager['simNumber' + iccNumber].textContent = number;
UIManager['simInfo' + iccNumber].classList.remove('no-number');
} else {
UIManager['simInfo' + iccNumber].classList.add('no-number');
}
}
},
showSIMInfoScreen: function sm_showSIMInfoScreen() {
this.updateSIMInfoText(this.icc0);
this.updateSIMInfoText(this.icc1);
UIManager.activationScreen.classList.remove('show');
UIManager.simInfoScreen.classList.add('show');
},
hideSIMInfoScreen: function sm_hidescreen() {
UIManager.simInfoScreen.classList.remove('show');
UIManager.activationScreen.classList.add('show');
},
checkSIMButton: function sm_checkSIMButton() {
if (!this.mobConn) {
UIManager.simImport.classList.add('hidden');
return;
}
var simOption = UIManager.simImportButton;
// If there is an unlocked SIM we activate import from SIM
if (!SimManager.alreadyImported && SimManager.available()) {
simOption.removeAttribute('disabled');
UIManager.noSim.classList.add('hidden');
} else {
simOption.setAttribute('disabled', 'disabled');
if (!SimManager.alreadyImported) {
UIManager.noSim.classList.remove('hidden');
}
}
},
showPinScreen: function sm_showPinScreen(icc) {
showRetryCount(icc, 'pin', UIManager.pinRetriesLeft);
// Button management
UIManager.unlockSimButton.disabled = true;
UIManager.pinInput.addEventListener('input', function sm_checkInput(event) {
UIManager.unlockSimButton.disabled = (event.target.value.length < 4);
});
// Screen management
UIManager.activationScreen.classList.remove('show');
UIManager.unlockSimScreen.classList.add('show');
UIManager.pincodeScreen.classList.add('show');
UIManager.xckcodeScreen.classList.remove('show');
UIManager.unlockSimHeader.setAttribute('data-l10n-id', 'pincode2');
if (this.simSlots > 1) {
var simNumber = icc === this.icc0 ? 1 : 2;
document.l10n.setAttributes(UIManager.pinLabel,
'pincodeLabel', {n: simNumber});
} else {
UIManager.pinLabel.setAttribute('data-l10n-id', 'type_pin');
}
UIManager.pinInput.focus();
},
showPukScreen: function sm_showPukScreen(icc) {
showRetryCount(icc, 'puk', UIManager.pukRetriesLeft);
UIManager.unlockSimScreen.classList.add('show');
UIManager.activationScreen.classList.remove('show');
UIManager.pincodeScreen.classList.remove('show');
UIManager.pukcodeScreen.classList.add('show');
UIManager.xckcodeScreen.classList.remove('show');
UIManager.unlockSimHeader.setAttribute('data-l10n-id', 'pukcode');
if (this.simSlots > 1) {
var simNumber = icc === this.icc0 ? 1 : 2;
document.l10n.setAttributes(UIManager.pukLabel,
'pukcodeLabel', {n: simNumber});
} else {
UIManager.pukLabel.setAttribute('data-l10n-id', 'type_puk');
}
UIManager.pukInput.focus();
},
showXckScreen: function sm_showXckScreen(icc) {
var lockType;
switch (icc.mozIcc.cardState) {
case 'networkLocked':
lockType = 'nck';
break;
case 'corporateLocked':
lockType = 'cck';
break;
case 'serviceProviderLocked':
lockType = 'spck';
break;
case 'network1Locked':
lockType = 'nck1';
break;
case 'network2Locked':
lockType = 'nck2';
break;
case 'hrpdNetworkLocked':
lockType = 'hnck';
break;
case 'ruimCorporateLocked':
lockType = 'rcck';
break;
case 'ruimServiceProviderLocked':
lockType = 'rspck';
break;
default:
return; // We shouldn't be here.
}
showRetryCount(icc, lockType, UIManager.xckRetriesLeft);
UIManager.unlockSimScreen.classList.add('show');
UIManager.activationScreen.classList.remove('show');
UIManager.pincodeScreen.classList.remove('show');
UIManager.pukcodeScreen.classList.remove('show');
UIManager.xckcodeScreen.classList.add('show');
var simNumber = icc === this.icc0 ? 1 : 2;
switch (icc.mozIcc.cardState) {
case 'networkLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'nckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'nckcodeLabel',
{n: simNumber});
break;
case 'corporateLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'cckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'cckcodeLabel',
{n: simNumber});
break;
case 'serviceProviderLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'spckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'spckcodeLabel',
{n: simNumber});
break;
case 'network1Locked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'nck1codeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'nck1codeLabel',
{n: simNumber});
break;
case 'network2Locked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'nck2codeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'nck2codeLabel',
{n: simNumber});
break;
case 'hrpdNetworkLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'hnckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'hnckcodeLabel',
{n: simNumber});
break;
case 'ruimCorporateLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'rcckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'rcckcodeLabel',
{n: simNumber});
break;
case 'ruimServiceProviderLocked':
document.l10n.setAttributes(UIManager.unlockSimHeader,
'rspckcodeTitle', {n: simNumber});
document.l10n.setAttributes(UIManager.xckLabel, 'rspckcodeLabel',
{n: simNumber});
break;
}
UIManager.xckInput.focus();
},
resetForm: function sm_clearInputs() {
this.clearFields();
UIManager.newpinInput.value = '';
UIManager.confirmNewpinInput.value = '';
UIManager.pinInput.value = '';
UIManager.pukInput.value = '';
UIManager.pukInfo.classList.remove('hidden');
UIManager.xckInput.value = '';
UIManager.unlockSimButton.disabled = false;
},
hideScreen: function sm_hideScreen() {
UIManager.unlockSimScreen.classList.remove('show');
UIManager.pincodeScreen.classList.remove('show');
UIManager.pukcodeScreen.classList.remove('show');
UIManager.xckcodeScreen.classList.remove('show');
UIManager.activationScreen.classList.add('show');
},
skip: function sm_skip() {
if (this._unlockingIcc) {
this._unlockingIcc.skipped = true;
}
this.resetForm();
this.hideScreen();
this.handleCardState();
},
resetSkipped: function sm_resetSkipped() {
if (this.icc0) {
this.icc0.skipped = false;
}
if (this.icc1) {
this.icc1.skipped = false;
}
},
back: function sm_back() {
this.resetForm();
this.resetSkipped();
this.hideScreen();
this.hideSIMInfoScreen();
Navigation.back();
},
simUnlockBack: function sm_simUnlockBack() {
if (this.icc0 && this.icc0.skipped) {
this.icc0.skipped = false;
this.hideScreen();
this.handleCardState();
} else {
this.back();
}
},
unlock: function sm_unlock() {
var icc = this._unlockingIcc;
if (!icc) {
throw new Error('Cannot unlock SIM, no current ICC');
}
this.clearFields();
switch (icc.mozIcc.cardState) {
case 'pinRequired':
this.unlockPin(icc);
break;
case 'pukRequired':
this.unlockPuk(icc);
break;
case 'networkLocked':
case 'corporateLocked':
case 'serviceProviderLocked':
case 'network1Locked':
case 'network2Locked':
case 'hrpdNetworkLocked':
case 'ruimCorporateLocked':
case 'ruimServiceProviderLocked':
this.unlockXck(icc);
break;
}
},
unlockPin: function sm_unlockPin(icc) {
var pin = UIManager.pinInput.value;
if (pin.length < 4 || pin.length > 8) {
UIManager.pinError.
querySelector('.main').setAttribute('data-l10n-id', 'pinValidation');
UIManager.pinInput.classList.add('onerror');
UIManager.pinError.classList.remove('hidden');
UIManager.pinInput.focus();
return;
} else {
UIManager.pinInput.classList.remove('onerror');
UIManager.pinError.classList.add('hidden');
}
// Unlock SIM
this.attemptUnlock(icc, {lockType: 'pin', pin: pin });
},
clearFields: function sm_clearFields() {
UIManager.pukInput.classList.remove('onerror');
UIManager.pukError.classList.add('hidden');
UIManager.newpinInput.classList.remove('onerror');
UIManager.newpinError.classList.add('hidden');
UIManager.confirmNewpinInput.classList.remove('onerror');
UIManager.confirmNewpinError.classList.add('hidden');
UIManager.pinError.classList.add('hidden');
UIManager.pinError.querySelector('.main').classList.add('hidden');
UIManager.pinError.querySelector('.lastchance').classList.add('hidden');
UIManager.pinRetriesLeft.classList.add('hidden');
UIManager.pukError.classList.add('hidden');
UIManager.pukError.querySelector('.main').classList.add('hidden');
UIManager.pukError.querySelector('.lastchance').classList.add('hidden');
UIManager.pukRetriesLeft.classList.add('hidden');
UIManager.xckError.classList.add('hidden');
UIManager.xckError.querySelector('.main').classList.add('hidden');
UIManager.xckError.querySelector('.lastchance').classList.add('hidden');
UIManager.xckRetriesLeft.classList.add('hidden');
},
unlockPuk: function sm_unlockPuk(icc) {
var pukCode = UIManager.pukInput.value;
if (pukCode.length !== 8) {
UIManager.pukError.querySelector('.main')
.setAttribute('data-l10n-id', 'pukValidation');
UIManager.pukError.classList.remove('hidden');
UIManager.pukInfo.classList.add('hidden');
UIManager.pukInput.classList.add('onerror');
UIManager.pukError.focus();
return;
}
var newpinCode = UIManager.newpinInput.value;
var confirmNewpin = UIManager.confirmNewpinInput.value;
if (newpinCode.length < 4 || newpinCode.length > 8) {
UIManager.newpinError.setAttribute('data-l10n-id', 'pinValidation');
UIManager.newpinError.classList.remove('hidden');
UIManager.newpinInput.classList.add('onerror');
UIManager.newpinError.focus();
return;
}
if (newpinCode != confirmNewpin) {
UIManager.confirmNewpinError.setAttribute('data-l10n-id',
'newpinConfirmation');
UIManager.confirmNewpinError.classList.remove('hidden');
UIManager.newpinInput.classList.add('onerror');
UIManager.confirmNewpinInput.classList.add('onerror');
UIManager.confirmNewpinError.focus();
return;
}
// Unlock SIM with PUK and new PIN
var options = {lockType: 'puk', puk: pukCode, newPin: newpinCode };
this.attemptUnlock(icc, options);
},
unlockXck: function sm_unlockXck(icc) {
var xck = UIManager.xckInput.value;
var lockType;
switch (icc.mozIcc.cardState) {
case 'networkLocked':
lockType = 'nck';
break;
case 'corporateLocked':
lockType = 'cck';
break;
case 'serviceProviderLocked':
lockType = 'spck';
break;
case 'network1Locked':
lockType = 'nck1';
break;
case 'network2Locked':
lockType = 'nck2';
break;
case 'hrpdNetworkLocked':
lockType = 'hnck';
break;
case 'ruimCorporateLocked':
lockType = 'rcck';
break;
case 'ruimServiceProviderLocked':
lockType = 'rspck';
break;
}
if (xck.length < 8 || xck.length > 16) {
UIManager.xckInput.classList.add('onerror');
UIManager.xckError.classList.remove('hidden');
UIManager.xckError.querySelector('.main').
setAttribute('data-l10n-id', lockType + 'Validation');
UIManager.xckInput.focus();
return;
} else {
UIManager.pinInput.classList.remove('onerror');
UIManager.pinError.classList.add('hidden');
}
// Unlock SIM
var options = {lockType: lockType, pin: xck };
this.attemptUnlock(icc, options);
},
attemptUnlock: function sm_attemptUnlock(icc, options) {
var req = icc.mozIcc.unlockCardLock(options);
req.onsuccess = (function sm_unlockSuccess() {
icc.unlocked = true;
this.resetForm();
this.hideScreen();
this.handleCardState();
}).bind(this);
req.onerror = (function sm_unlockError() {
this.handleUnlockError(options.lockType, req.error.retryCount);
}).bind(this);
},
// Try to infer whats the default SIM
guessIcc: function guessIcc() {
var tempIcc = null;
if (navigator.mozMobileConnections) {
// New multi-sim api, use mozMobileConnections to guess
// the first inserted sim
for (var i = 0;
i < navigator.mozMobileConnections.length && tempIcc === null; i++) {
if (navigator.mozMobileConnections[i] !== null &&
navigator.mozMobileConnections[i].iccId !== null) {
tempIcc = navigator.mozIccManager.getIccById(
navigator.mozMobileConnections[i].iccId);
}
}
} else {
tempIcc = navigator.mozIccManager;
}
return tempIcc;
},
importContacts: function sm_importContacts() {
// Delay for showing feedback to the user after importing
var DELAY_FEEDBACK = 300;
UIManager.navBar.setAttribute('aria-disabled', 'true');
var progress = utils.overlay.show('simContacts-reading',
'activityBar');
var importButton = UIManager.simImportButton;
var cancelled = false,
contactsRead = false;
var importer = new SimContactsImporter(SimManager.guessIcc());
utils.overlay.showMenu();
utils.overlay.oncancel = function oncancel() {
cancelled = true;
importer.finish();
if (contactsRead) {
// A message about canceling will be displayed while the current chunk
// is being cooked
progress.setClass('activityBar');
utils.overlay.hideMenu();
progress.setHeaderMsg('messageCanceling');
} else {
importer.onfinish(); // Early return while reading contacts
}
};
var importedContacts = 0;
importer.onread = function sim_import_read(n) {
contactsRead = true;
if (n > 0) {
progress.setClass('progressBar');
progress.setHeaderMsg('simContacts-importing');
progress.setTotal(n);
}
};
importer.onimported = function imported_contact() {
importedContacts++;
if (!cancelled) {
progress.update();
}
};
importer.onfinish = function sim_import_finish(numDupsMerged, iccId) {
window.setTimeout(function do_sim_import_finish() {
UIManager.navBar.removeAttribute('aria-disabled');
utils.overlay.hide();
if (importedContacts > 0) {
utils.misc.setTimestamp('sim-' + iccId);
}
if (!cancelled) {
SimManager.alreadyImported = true;
importButton.setAttribute('disabled', 'disabled');
utils.status.show({
id: 'simContacts-imported3',
args: {n: importedContacts}
});
}
}, DELAY_FEEDBACK);
importer.onfinish = null;
};
importer.onerror = function sim_import_error() {
UIManager.navBar.removeAttribute('aria-disabled');
utils.overlay.hide();
// Just in case the user decides to do so later
importButton.removeAttribute('disabled');
// Showing error message allowing user to retry
var cancel = {
title: 'cancel',
callback: function() {
ConfirmDialog.hide();
}
};
var retry = {
title: 'retry',
isRecommend: true,
callback: function() {
ConfirmDialog.hide();
// And now the action is reproduced one more time
importButton.click();
}
};
ConfirmDialog.show(null, 'simContacts-error', cancel, retry);
}; // importer.onerror
importer.start();
}
};
})();