VulpesOS/gaia/apps/system/js/sim_lock_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

284 lines
8.3 KiB
JavaScript
Executable file

/* global SIMSlotManager, Service, BaseModule, applications */
'use strict';
(function(exports) {
var SimLockManager = function(core) {
this.mobileConnections = core.mobileConnections;
};
SimLockManager.EVENTS = [
'simslotready',
'ftuopen',
'appopened',
'lockscreen-request-unlock',
'simslot-updated',
'simslot-cardstatechange',
'simslot-iccinfochange',
'attentionopening',
'attentionterminated',
'simlockskip',
'simlockback',
'simlockrequestclose',
'airplanemode-enabled',
'rocketbar-activating'
];
SimLockManager.SUB_MODULES = [
'SimLockSystemDialog'
];
BaseModule.create(SimLockManager, {
name: 'SimLockManager',
_duringCall: false,
_showPrevented: false,
_alreadyShown: false,
_handle_simslotready: function() {
this.showIfLocked();
},
_sim_lock_system_dialog_loaded: function() {
this.showIfLocked();
},
'_handle_simslot-updated': function(evt) {
this.showIfLocked(evt.detail.index);
},
'_handle_simslot-iccinfochange': function(evt) {
this.showIfLocked(evt.detail.index);
},
'_handle_simslot-cardstatechange': function(evt) {
this.showIfLocked(evt.detail.index);
},
'_handle_ftuopen': function() {
if (this.service.query('justUpgraded') === false) {
this.simLockSystemDialog.close();
} else {
this.showIfLocked();
}
},
_handle_simlockback: function(evt) {
var index = evt.detail._currentSlot.index;
this.showIfLocked(index - 1, false);
},
_handle_simlockskip: function(evt) {
var index = evt.detail._currentSlot.index;
if (index + 1 > this.mobileConnections.length - 1) {
evt.detail.close('skip');
} else {
if (!this.showIfLocked(index + 1, true)) {
evt.detail.close('skip');
}
}
},
_handle_simlockrequestclose: function(evt) {
var index = evt.detail._currentSlot.index;
if (index + 1 > this.mobileConnections.length - 1) {
evt.detail.close();
} else {
if (!this.showIfLocked(index + 1, false)) {
evt.detail.close();
}
}
},
_handle_attentionopening: function(evt) {
if (evt.detail.CLASS_NAME !== 'CallscreenWindow') {
return;
}
this._duringCall = true;
},
_handle_attentionterminated: function(evt) {
if (evt.detail.CLASS_NAME !== 'CallscreenWindow') {
return;
}
this._duringCall = false;
if (this._showPrevented) {
this._showPrevented = false;
// We show the SIM dialog right away otherwise the user won't
// be able to receive calls.
this.showIfLocked();
}
},
'_handle_lockscreen-request-unlock': function(evt) {
// Check whether the lock screen was unlocked from the camera or not.
// If the former is true, the SIM PIN dialog should not displayed after
// unlock, because the camera will be opened (Bug 849718)
if (evt.detail && evt.detail.activity &&
'record' === evt.detail.activity.name) {
this.simLockSystemDialog.close();
return;
}
var self = this;
// We should wait for lockscreen-appclosed event sent before checking
// the value of Service.query('locked') in showIfLocked method.
window.addEventListener('lockscreen-appclosed',
function lockscreenOnClosed() {
window.removeEventListener('lockscreen-appclosed',
lockscreenOnClosed);
self.showIfLocked();
});
},
_handle_appopened: function(evt) {
// If an app needs 'telephony' or 'sms' permissions (i.e. mobile
// connection) and the SIM card is locked, the SIM PIN unlock screen
// should be launched
var app = evt.detail;
if (!app || !app.manifest || !app.manifest.permissions) {
return;
}
// Ignore apps that don't require a mobile connection
if (!('telephony' in app.manifest.permissions ||
'sms' in app.manifest.permissions)) {
return;
}
// If the Settings app will open, don't prompt for SIM PIN entry
// although it has 'telephony' permission (Bug 861206)
var settingsManifestURL =
'app://settings.gaiamobile.org/manifest.webapp';
if (app.manifestURL == settingsManifestURL) {
if (this.simLockSystemDialog.visible) {
this.simLockSystemDialog.close();
}
return;
}
// If SIM is locked, cancel app opening in order to display
// it after the SIM PIN dialog is shown
this.showIfLocked();
// XXX: We don't block the app from launching if it requires SIM
// but only put the SIM PIN dialog upon the opening/opened app.
// Will revisit this in
// https://bugzilla.mozilla.org/show_bug.cgi?id=SIMPIN-Dialog
},
'_handle_airplanemode-enabled': function(evt) {
this.simLockSystemDialog.close();
this._alreadyShown = false;
},
'_handle_rocketbar-activating': function(evt) {
this.simLockSystemDialog.close();
this._alreadyShown = false;
},
isBothSlotsLocked: function sl_isBothSlotsLocked() {
if (!SIMSlotManager.isMultiSIM() ||
SIMSlotManager.hasOnlyOneSIMCardDetected()) {
return false;
}
var simSlots = SIMSlotManager.getSlots();
var isBothLocked = true;
for (var i = 0; i < simSlots.length; i++) {
var currentSlot = simSlots[i];
var unknownState = currentSlot.isUnknownState();
var currentLocked = currentSlot.isLocked() || unknownState;
isBothLocked = isBothLocked && currentLocked;
}
return isBothLocked;
},
showIfLocked: function sl_showIfLocked(currentSlotIndex, skipped) {
if (!SIMSlotManager.ready) {
this.warn('SIMSlot not ready yet.');
return false;
}
if (!this.simLockSystemDialog) {
this.warn('dialog not ready.');
return false;
}
if (Service.query('locked')) {
this.warn('Lockscreen is on so hidden.');
return false;
}
if (currentSlotIndex === null && this.simLockSystemDialog.visible) {
this.warn('Already displayed.');
return false;
}
// FTU has its specific SIM PIN UI
if (this.service.query('isFtuRunning') &&
!this.service.query('justUpgraded')) {
this.warn('Running full ftu.');
this.simLockSystemDialog.close();
return false;
}
if (this._duringCall) {
this.warn('During call');
this._showPrevented = true;
return false;
}
if (!applications.ready) {
return false;
}
return SIMSlotManager.getSlots().some(function iterator(slot, index) {
// If currentSlotIndex is present then we just need to handle this slot
if (currentSlotIndex && index !== currentSlotIndex) {
return false;
}
if (!slot.simCard) {
this.warn('No SIM card in slot ' + (index + 1));
return false;
}
// Only render if not already displaying, or
// displaying and skipping
if (skipped == null && this.simLockSystemDialog.visible) {
return false;
}
// Always showing the first slot first.
if (!this._alreadyShown && this.isBothSlotsLocked() && index > 0) {
return false;
}
switch (slot.getCardState()) {
// do nothing in either unknown or null card states
case null:
case 'unknown':
this.warn('unknown SIM card state for slot ' + (index + 1));
break;
case 'pukRequired':
case 'pinRequired':
this.simLockSystemDialog.show(slot, skipped);
this._alreadyShown = true;
return true;
case 'networkLocked':
case 'corporateLocked':
case 'serviceProviderLocked':
case 'network1Locked':
case 'network2Locked':
case 'hrpdNetworkLocked':
case 'ruimCorporateLocked':
case 'ruimServiceProviderLocked':
this.simLockSystemDialog.show(slot, skipped);
this._alreadyShown = true;
return true;
default:
this.warn('SIM slot ' + (index + 1) + ' is not locked, skipping');
return false;
}
}, this);
}
});
}());