Bug 963054 - Wait card state initialization. r=hsinyi

This commit is contained in:
Szu-Yu Chen [:aknow] 2014-02-14 17:42:32 +08:00
Родитель 84c89c99e5
Коммит dda2360ef6
3 изменённых файлов: 73 добавлений и 46 удалений

Просмотреть файл

@ -508,49 +508,73 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function() {
});
XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
return {
ril: null,
pendingMessages: [], // For queueing "RIL:SetRadioEnabled" messages.
timer: null,
request: null,
deactivatingDeferred: {},
let _ril = null;
let _pendingMessages = []; // For queueing "RIL =SetRadioEnabled" messages.
let _isProcessingPending = false;
let _timer = null;
let _request = null;
let _deactivatingDeferred = {};
let _initializedCardState = {};
let _allCardStateInitialized = !RILQUIRKS_RADIO_OFF_WO_CARD;
return {
init: function(ril) {
this.ril = ril;
_ril = ril;
},
receiveMessage: function(msg) {
if (DEBUG) debug("setRadioEnabled: receiveMessage: " + JSON.stringify(msg));
this.pendingMessages.push(msg);
if (this.pendingMessages.length === 1 && !this.isDeactivatingDataCalls()) {
this._processNextMessage();
receiveCardState: function(clientId) {
if (_allCardStateInitialized) {
return;
}
if (DEBUG) debug("RadioControl: receive cardState from " + clientId);
_initializedCardState[clientId] = true;
if (Object.keys(_initializedCardState).length == _ril.numRadioInterfaces) {
_allCardStateInitialized = true;
this._startProcessingPending();
}
},
receiveMessage: function(msg) {
if (DEBUG) debug("RadioControl: receiveMessage: " + JSON.stringify(msg));
_pendingMessages.push(msg);
this._startProcessingPending();
},
isDeactivatingDataCalls: function() {
return this.request !== null;
return _request !== null;
},
finishDeactivatingDataCalls: function(clientId) {
if (DEBUG) debug("setRadioEnabled: finishDeactivatingDataCalls: " + clientId);
let deferred = this.deactivatingDeferred[clientId];
if (DEBUG) debug("RadioControl: finishDeactivatingDataCalls: " + clientId);
let deferred = _deactivatingDeferred[clientId];
if (deferred) {
deferred.resolve();
}
},
_startProcessingPending: function() {
if (!_isProcessingPending) {
if (DEBUG) debug("RadioControl: start dequeue");
_isProcessingPending = true;
this._processNextMessage();
}
},
_processNextMessage: function() {
if (this.pendingMessages.length === 0) {
if (_pendingMessages.length === 0 || !_allCardStateInitialized) {
if (DEBUG) debug("RadioControl: stop dequeue");
_isProcessingPending = false;
return;
}
let msg = this.pendingMessages.shift();
let msg = _pendingMessages.shift();
this._handleMessage(msg);
},
_getNumCards: function() {
let numCards = 0;
for (let i = 0, N = this.ril.numRadioInterfaces; i < N; ++i) {
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
if (this._isCardPresentAtClient(i)) {
numCards++;
}
@ -559,7 +583,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
},
_isCardPresentAtClient: function(clientId) {
let cardState = this.ril.getRadioInterface(clientId).rilContext.cardState;
let cardState = _ril.getRadioInterface(clientId).rilContext.cardState;
return cardState !== RIL.GECKO_CARDSTATE_UNDETECTED &&
cardState !== RIL.GECKO_CARDSTATE_UNKNOWN;
},
@ -586,9 +610,9 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
},
_handleMessage: function(msg) {
if (DEBUG) debug("setRadioEnabled: handleMessage: " + JSON.stringify(msg));
if (DEBUG) debug("RadioControl: handleMessage: " + JSON.stringify(msg));
let clientId = msg.json.clientId || 0;
let radioInterface = this.ril.getRadioInterface(clientId);
let radioInterface = _ril.getRadioInterface(clientId);
if (!radioInterface.isValidStateForSetRadioEnabled()) {
radioInterface.setRadioEnabledResponse(msg.target, msg.json.data,
@ -613,17 +637,17 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
this._processNextMessage();
} else {
this.request = (function() {
_request = function() {
radioInterface.receiveMessage(msg);
}).bind(this);
};
// In 2G network, modem takes 35+ seconds to process deactivate data
// call request if device has active voice call (please see bug 964974
// for more details). Therefore we should hangup all active voice calls
// first. And considering some DSDS architecture, toggling one radio may
// toggle both, so we send hangUpAll to all clients.
for (let i = 0, N = this.ril.numRadioInterfaces; i < N; ++i) {
let iface = this.ril.getRadioInterface(i);
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
let iface = _ril.getRadioInterface(i);
iface.workerMessenger.send("hangUpAll");
}
@ -631,7 +655,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
// toggle both. Therefore, for safely turning off, we should first
// explicitly deactivate all data calls from all clients.
this._deactivateDataCalls().then(() => {
if (DEBUG) debug("setRadioEnabled: deactivation done");
if (DEBUG) debug("RadioControl: deactivation done");
this._executeRequest();
});
@ -640,11 +664,11 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
},
_deactivateDataCalls: function() {
if (DEBUG) debug("setRadioEnabled: deactivating data calls...");
this.deactivatingDeferred = {};
if (DEBUG) debug("RadioControl: deactivating data calls...");
_deactivatingDeferred = {};
let promise = Promise.resolve();
for (let i = 0, N = this.ril.numRadioInterfaces; i < N; ++i) {
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
promise = promise.then(this._deactivateDataCallsForClient(i));
}
@ -652,35 +676,35 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
},
_deactivateDataCallsForClient: function(clientId) {
return (function() {
let deferred = this.deactivatingDeferred[clientId] = Promise.defer();
return function() {
let deferred = _deactivatingDeferred[clientId] = Promise.defer();
let dataConnectionHandler = gDataConnectionManager.getConnectionHandler(clientId);
dataConnectionHandler.deactivateDataCalls();
return deferred.promise;
}).bind(this);
};
},
_createTimer: function() {
if (!this.timer) {
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
if (_timer) {
_timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
}
this.timer.initWithCallback(this._executeRequest.bind(this),
RADIO_POWER_OFF_TIMEOUT,
Ci.nsITimer.TYPE_ONE_SHOT);
_timer.initWithCallback(this._executeRequest.bind(this),
RADIO_POWER_OFF_TIMEOUT,
Ci.nsITimer.TYPE_ONE_SHOT);
},
_cancelTimer: function() {
if (this.timer) {
this.timer.cancel();
if (_timer) {
_timer.cancel();
}
},
_executeRequest: function() {
if (typeof this.request === "function") {
if (DEBUG) debug("setRadioEnabled: executeRequest");
if (typeof _request === "function") {
if (DEBUG) debug("RadioControl: executeRequest");
this._cancelTimer();
this.request();
this.request = null;
_request();
_request = null;
}
this._processNextMessage();
},
@ -2155,6 +2179,7 @@ RadioInterface.prototype = {
break;
case "cardstatechange":
this.rilContext.cardState = message.cardState;
gRadioEnabledController.receiveCardState(this.clientId);
gMessageManager.sendIccMessage("RIL:CardStateChanged",
this.clientId, message);
break;

Просмотреть файл

@ -2432,6 +2432,7 @@ this.GECKO_DETAILED_RADIOSTATE_ENABLED = "enabled";
this.GECKO_DETAILED_RADIOSTATE_DISABLING = "disabling";
this.GECKO_DETAILED_RADIOSTATE_DISABLED = "disabled";
this.GECKO_CARDSTATE_UNINITIALIZED = "uninitialized";
this.GECKO_CARDSTATE_UNDETECTED = null;
this.GECKO_CARDSTATE_ILLEGAL = "illegal";
this.GECKO_CARDSTATE_UNKNOWN = "unknown";

Просмотреть файл

@ -280,7 +280,7 @@ let RIL = {
/**
* Card state
*/
this.cardState = GECKO_CARDSTATE_UNDETECTED;
this.cardState = GECKO_CARDSTATE_UNINITIALIZED;
/**
* Strings
@ -2988,8 +2988,9 @@ let RIL = {
this.appType = app.app_type;
this.iccInfo.iccType = GECKO_CARD_TYPE[this.appType];
// Try to get iccId only when cardState left GECKO_CARDSTATE_UNDETECTED.
if (this.cardState === GECKO_CARDSTATE_UNDETECTED &&
iccStatus.cardState === CARD_STATE_PRESENT) {
if (iccStatus.cardState === CARD_STATE_PRESENT &&
(this.cardState === GECKO_CARDSTATE_UNINITIALIZED ||
this.cardState === GECKO_CARDSTATE_UNDETECTED)) {
ICCRecordHelper.readICCID();
}