Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
240 lines
7.9 KiB
JavaScript
240 lines
7.9 KiB
JavaScript
/* global BaseModule, asyncStorage, SIMSlotManager, SettingsHelper,
|
|
CallForwardingsIcon, LazyLoader */
|
|
'use strict';
|
|
|
|
(function() {
|
|
// Must be in sync with nsIDOMMozMobileCFInfo interface.
|
|
var _cfReason = {
|
|
CALL_FORWARD_REASON_UNCONDITIONAL: 0,
|
|
CALL_FORWARD_REASON_MOBILE_BUSY: 1,
|
|
CALL_FORWARD_REASON_NO_REPLY: 2,
|
|
CALL_FORWARD_REASON_NOT_REACHABLE: 3,
|
|
CALL_FORWARD_REASON_ALL_CALL_FORWARDING: 4,
|
|
CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING: 5
|
|
};
|
|
var _cfAction = {
|
|
CALL_FORWARD_ACTION_DISABLE: 0,
|
|
CALL_FORWARD_ACTION_ENABLE: 1,
|
|
CALL_FORWARD_ACTION_QUERY_STATUS: 2,
|
|
CALL_FORWARD_ACTION_REGISTRATION: 3,
|
|
CALL_FORWARD_ACTION_ERASURE: 4
|
|
};
|
|
|
|
/**
|
|
* The module initializes the call forwarding icon states and update the icons
|
|
* when call forwarding states changed.
|
|
* As we are not able to query the current call forwarding states from the
|
|
* carrier on startup, we initialized the icon state based on the cached
|
|
* information. When call forwarding states are changed, the module caches
|
|
* the state along with the corresponding iccId.
|
|
* @class CallForwarding
|
|
* @requires SIMSlotManager
|
|
* @requires SettingsHelper
|
|
*/
|
|
function CallForwarding() {
|
|
this._slots = null;
|
|
this._callForwardingHelper = null;
|
|
this._defaultCallForwardingIconStates = null;
|
|
this._callForwardingIconInitializedStates = null;
|
|
}
|
|
CallForwarding.STATES = [
|
|
'enabled'
|
|
];
|
|
CallForwarding.SETTINGS = [
|
|
'ril.cf.enabled'
|
|
];
|
|
|
|
BaseModule.create(CallForwarding, {
|
|
name: 'CallForwarding',
|
|
|
|
/**
|
|
* Add related event handlers. The sim cards may not be ready when starting.
|
|
* We register to "simslot-cardstatechange" and "simslot-iccinfochange" for
|
|
* updating the icons when ready. When users query the current call
|
|
* forwarding states in settings app, 'ril.cf.carrier.enabled' is used to
|
|
* notify the state changes. When users change the call forwarding states in
|
|
* settings app, we will receive the 'cfstatechange' event. All the events
|
|
* must be watched to have correct icon states.
|
|
* @memberof CallForwarding.prototype
|
|
*/
|
|
_addEventHandlers: function() {
|
|
window.addEventListener('simslot-cardstatechange', (function(event) {
|
|
this._initCallForwardingState(event.detail);
|
|
}).bind(this));
|
|
window.addEventListener('simslot-iccinfochange', (function(event) {
|
|
this._initCallForwardingState(event.detail);
|
|
}).bind(this));
|
|
|
|
// Get notified when users query the latest call forwarding states in
|
|
// settings app
|
|
navigator.mozSettings.addObserver('ril.cf.carrier.enabled',
|
|
(function(event) {
|
|
var detail = event.settingValue;
|
|
if (detail) {
|
|
this._onCallForwardingStateChanged(detail.index, detail.enabled);
|
|
}
|
|
}).bind(this));
|
|
|
|
this._slots.forEach(function(slot) {
|
|
var conn = slot.conn;
|
|
conn.addEventListener('cfstatechange',
|
|
this._updateCallForwardingIconState.bind(this, slot));
|
|
}, this);
|
|
},
|
|
|
|
/**
|
|
* Initialize the icon states based on iccId and cached information.
|
|
* @param {SIMSlot} slot The target sim slot.
|
|
* @memberof CallForwarding.prototype
|
|
*/
|
|
_initCallForwardingState: function(slot) {
|
|
var index = slot.index;
|
|
var simCard = slot.simCard;
|
|
|
|
if (this._callForwardingIconInitializedStates[index]) {
|
|
return;
|
|
}
|
|
|
|
var that = this;
|
|
var cardState = simCard && simCard.cardState;
|
|
var iccid = simCard && simCard.iccInfo && simCard.iccInfo.iccid;
|
|
// Disable call forwarding icon and early return when:
|
|
// 1. sim card not present, or
|
|
// 2. sim card state is not ready, or
|
|
// 3. sim card iccId is not available.
|
|
if (!simCard || cardState !== 'ready' || !iccid) {
|
|
that._callForwardingHelper.get(function(states) {
|
|
states[index] = false;
|
|
that._callForwardingHelper.set(states);
|
|
});
|
|
return;
|
|
}
|
|
|
|
asyncStorage.getItem('ril.cf.enabled.' + iccid, function(value) {
|
|
if (value === null) {
|
|
value = false;
|
|
}
|
|
that._callForwardingHelper.get(function(states) {
|
|
states[index] = value;
|
|
that._callForwardingHelper.set(states, function() {
|
|
that._callForwardingIconInitializedStates[index] = true;
|
|
});
|
|
});
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Gets called when receiving "cfstatechange". It updates the cached
|
|
* information and icon states.
|
|
* @param {SIMSlot} slot The target sim slot.
|
|
* @param {Event} event The event.
|
|
* @memberof CallForwarding.prototype
|
|
*/
|
|
_updateCallForwardingIconState: function(slot, event) {
|
|
if (!event ||
|
|
(event.reason != _cfReason.CALL_FORWARD_REASON_UNCONDITIONAL &&
|
|
event.reason != _cfReason.CALL_FORWARD_REASON_ALL_CALL_FORWARDING)) {
|
|
return;
|
|
}
|
|
|
|
var index = slot.index;
|
|
var simCard = slot.simCard;
|
|
|
|
var enabled = false;
|
|
switch (event.action) {
|
|
case _cfAction.CALL_FORWARD_ACTION_REGISTRATION:
|
|
case _cfAction.CALL_FORWARD_ACTION_ENABLE:
|
|
enabled = true;
|
|
break;
|
|
case _cfAction.CALL_FORWARD_ACTION_ERASURE:
|
|
enabled = false;
|
|
break;
|
|
default:
|
|
enabled = false;
|
|
break;
|
|
}
|
|
|
|
this._callForwardingHelper.get((function(states) {
|
|
states[index] = enabled;
|
|
this._callForwardingHelper.set(states);
|
|
}).bind(this));
|
|
|
|
if (!simCard) {
|
|
return;
|
|
}
|
|
var iccid = simCard.iccInfo && simCard.iccInfo.iccid;
|
|
asyncStorage.setItem('ril.cf.enabled.' + iccid, enabled);
|
|
},
|
|
|
|
/**
|
|
* Gets called when 'ril.cf.carrier.enabled' changes. It updates the cached
|
|
* information and icon states.
|
|
* @param {Number} index The index of the sim card being changed.
|
|
* @param {Boolean} enabled The call forwarding state.
|
|
* @memberof CallForwarding.prototype
|
|
*/
|
|
_onCallForwardingStateChanged: function(index, enabled) {
|
|
this._callForwardingHelper.get((function(states) {
|
|
states[index] = enabled;
|
|
this._callForwardingHelper.set(states);
|
|
}).bind(this));
|
|
|
|
var simCard = this._slots[index].simCard;
|
|
if (!simCard) {
|
|
return;
|
|
}
|
|
var iccid = simCard.iccInfo && simCard.iccInfo.iccid;
|
|
asyncStorage.setItem('ril.cf.enabled.' + iccid, enabled);
|
|
},
|
|
|
|
enabled: function(index) {
|
|
return this._enabled[index];
|
|
},
|
|
|
|
/**
|
|
* Start the module.
|
|
* @memberof CallForwarding.prototype
|
|
*/
|
|
_start: function() {
|
|
this._slots = SIMSlotManager.getSlots();
|
|
this._enabled = [];
|
|
this._defaultCallForwardingIconStates =
|
|
Array.prototype.map.call(this._slots, function() { return false; });
|
|
this._callForwardingIconInitializedStates =
|
|
Array.prototype.map.call(this._slots, function() { return false; });
|
|
|
|
// XXX:
|
|
// We should use observe/read/write functionality in baseModule
|
|
// and remove the usage here.
|
|
LazyLoader.load(['shared/js/settings_helper.js']).then(() => {
|
|
this._callForwardingHelper =
|
|
SettingsHelper('ril.cf.enabled',
|
|
this._defaultCallForwardingIconStates);
|
|
|
|
this._addEventHandlers();
|
|
|
|
// Initialize the icon states
|
|
this._slots.forEach(function(slot) {
|
|
this._initCallForwardingState(slot);
|
|
}, this);
|
|
}).catch((err) => {
|
|
console.error(err);
|
|
});
|
|
},
|
|
|
|
'_observe_ril.cf.enabled': function(value) {
|
|
this._enabled = value || [];
|
|
var isAnyEnabled =
|
|
this._enabled.some(function(enabled) { return enabled; });
|
|
if (!this.icon && isAnyEnabled) {
|
|
LazyLoader.load(['js/call_forwarding_icon.js']).then(function() {
|
|
this.icon = new CallForwardingsIcon(this);
|
|
this.icon.start();
|
|
}.bind(this)).catch(function(err) {
|
|
console.error(err);
|
|
});
|
|
}
|
|
this.icon && this.icon.update();
|
|
}
|
|
});
|
|
})();
|