зеркало из https://github.com/mozilla/gecko-dev.git
Bug 856553 - Part 4: Add setRadioEnabled API (ril). r=hsinyi
This commit is contained in:
Родитель
d63e9055db
Коммит
5b8c158332
|
@ -101,6 +101,8 @@ const RIL_IPC_MSG_NAMES = [
|
|||
"RIL:SetRoamingPreference",
|
||||
"RIL:GetRoamingPreference",
|
||||
"RIL:ExitEmergencyCbMode",
|
||||
"RIL:SetRadioEnabled",
|
||||
"RIL:RadioStateChanged",
|
||||
"RIL:SetVoicePrivacyMode",
|
||||
"RIL:GetVoicePrivacyMode",
|
||||
"RIL:OtaStatusChanged"
|
||||
|
@ -459,6 +461,7 @@ function RILContentHelper() {
|
|||
this.rilContexts[clientId] = {
|
||||
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
|
||||
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
|
||||
radioState: null,
|
||||
iccInfo: null,
|
||||
voiceConnectionInfo: new MobileConnectionInfo(),
|
||||
dataConnectionInfo: new MobileConnectionInfo()
|
||||
|
@ -611,6 +614,7 @@ RILContentHelper.prototype = {
|
|||
}
|
||||
this.rilContexts[cId].cardState = rilContext.cardState;
|
||||
this.rilContexts[cId].networkSelectionMode = rilContext.networkSelectionMode;
|
||||
this.rilContexts[cId].radioState = rilContext.detailedRadioState;
|
||||
this.updateIccInfo(cId, rilContext.iccInfo);
|
||||
this.updateConnectionInfo(rilContext.voice, this.rilContexts[cId].voiceConnectionInfo);
|
||||
this.updateConnectionInfo(rilContext.data, this.rilContexts[cId].dataConnectionInfo);
|
||||
|
@ -657,6 +661,11 @@ RILContentHelper.prototype = {
|
|||
return context && context.networkSelectionMode;
|
||||
},
|
||||
|
||||
getRadioState: function getRadioState(clientId) {
|
||||
let context = this.getRilContext(clientId);
|
||||
return context && context.radioState;
|
||||
},
|
||||
|
||||
/**
|
||||
* The networks that are currently trying to be selected (or "automatic").
|
||||
* This helps ensure that only one network per client is selected at a time.
|
||||
|
@ -1362,6 +1371,25 @@ RILContentHelper.prototype = {
|
|||
return request;
|
||||
},
|
||||
|
||||
setRadioEnabled: function setRadioEnabled(clientId, window, enabled) {
|
||||
if (window == null) {
|
||||
throw Components.Exception("Can't get window object",
|
||||
Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
let request = Services.DOMRequest.createRequest(window);
|
||||
let requestId = this.getRequestId(request);
|
||||
|
||||
cpmm.sendAsyncMessage("RIL:SetRadioEnabled", {
|
||||
clientId: clientId,
|
||||
data: {
|
||||
requestId: requestId,
|
||||
enabled: enabled,
|
||||
}
|
||||
});
|
||||
|
||||
return request;
|
||||
},
|
||||
|
||||
_mobileConnectionListeners: null,
|
||||
_cellBroadcastListeners: null,
|
||||
_voicemailListeners: null,
|
||||
|
@ -1767,6 +1795,16 @@ RILContentHelper.prototype = {
|
|||
"notifyEmergencyCbModeChanged",
|
||||
[data.active, data.timeoutMs]);
|
||||
break;
|
||||
case "RIL:SetRadioEnabled":
|
||||
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
|
||||
break;
|
||||
case "RIL:RadioStateChanged":
|
||||
this.rilContexts[clientId].radioState = data;
|
||||
this._deliverEvent(clientId,
|
||||
"_mobileConnectionListeners",
|
||||
"notifyRadioStateChanged",
|
||||
null);
|
||||
break;
|
||||
case "RIL:SetVoicePrivacyMode":
|
||||
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
|
||||
break;
|
||||
|
@ -2094,4 +2132,3 @@ RILContentHelper.prototype = {
|
|||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RILContentHelper,
|
||||
DOMMMIError,
|
||||
IccCardLockError]);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Sntp.jsm");
|
||||
Cu.import("resource://gre/modules/systemlibs.js");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
var RIL = {};
|
||||
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
||||
|
@ -106,6 +107,7 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
|
|||
"RIL:SetRoamingPreference",
|
||||
"RIL:GetRoamingPreference",
|
||||
"RIL:ExitEmergencyCbMode",
|
||||
"RIL:SetRadioEnabled",
|
||||
"RIL:SetVoicePrivacyMode",
|
||||
"RIL:GetVoicePrivacyMode"
|
||||
];
|
||||
|
@ -417,6 +419,11 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (msg.name === "RIL:SetRadioEnabled") {
|
||||
// Special handler for SetRadioEnabled.
|
||||
return gRadioEnabledController.receiveMessage(msg);
|
||||
}
|
||||
|
||||
return radioInterface.receiveMessage(msg);
|
||||
},
|
||||
|
||||
|
@ -466,7 +473,131 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
|
|||
};
|
||||
});
|
||||
|
||||
// Initialize shared preference 'ril.numRadioInterfaces' according to system
|
||||
XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function () {
|
||||
return {
|
||||
ril: null,
|
||||
pendingMessages: [], // For queueing "RIL:SetRadioEnabled" messages.
|
||||
timer: null,
|
||||
request: null,
|
||||
deactivatingDeferred: {},
|
||||
|
||||
init: function init(ril) {
|
||||
this.ril = ril;
|
||||
},
|
||||
|
||||
receiveMessage: function(msg) {
|
||||
if (DEBUG) debug("setRadioEnabled: receiveMessage: " + JSON.stringify(msg));
|
||||
this.pendingMessages.push(msg);
|
||||
if (this.pendingMessages.length === 1) {
|
||||
this._processNextMessage();
|
||||
}
|
||||
},
|
||||
|
||||
isDeactivatingDataCalls: function() {
|
||||
return this.request !== null;
|
||||
},
|
||||
|
||||
finishDeactivatingDataCalls: function(clientId) {
|
||||
if (DEBUG) debug("setRadioEnabled: finishDeactivatingDataCalls: " + clientId);
|
||||
let deferred = this.deactivatingDeferred[clientId];
|
||||
if (deferred) {
|
||||
deferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
_processNextMessage: function() {
|
||||
if (this.pendingMessages.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let msg = this.pendingMessages.shift();
|
||||
this._handleMessage(msg);
|
||||
},
|
||||
|
||||
_handleMessage: function(msg) {
|
||||
if (DEBUG) debug("setRadioEnabled: handleMessage: " + JSON.stringify(msg));
|
||||
let radioInterface = this.ril.getRadioInterface(msg.json.clientId || 0);
|
||||
|
||||
if (!radioInterface.isValidStateForSetRadioEnabled()) {
|
||||
radioInterface.setRadioEnabledResponse(msg.target, msg.json.data,
|
||||
"InvalidStateError");
|
||||
this._processNextMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (radioInterface.isDummyForSetRadioEnabled(msg.json.data)) {
|
||||
radioInterface.setRadioEnabledResponse(msg.target, msg.json.data);
|
||||
this._processNextMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.json.data.enabled) {
|
||||
radioInterface.receiveMessage(msg);
|
||||
this._processNextMessage();
|
||||
} else {
|
||||
this.request = (function() {
|
||||
radioInterface.receiveMessage(msg);
|
||||
this._processNextMessage();
|
||||
}).bind(this);
|
||||
|
||||
// In some DSDS architecture with only one modem, toggling one radio may
|
||||
// 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");
|
||||
this._executeRequest();
|
||||
});
|
||||
|
||||
this._createTimer();
|
||||
}
|
||||
},
|
||||
|
||||
_deactivateDataCalls: function() {
|
||||
if (DEBUG) debug("setRadioEnabled: deactivating data calls...");
|
||||
this.deactivatingDeferred = {};
|
||||
|
||||
let promise = Promise.resolve();
|
||||
for (let i = 0, N = this.ril.numRadioInterfaces; i < N; ++i) {
|
||||
promise = promise.then(this._deactivateDataCallsForClient(i));
|
||||
}
|
||||
|
||||
return promise;
|
||||
},
|
||||
|
||||
_deactivateDataCallsForClient: function(clientId) {
|
||||
return (function() {
|
||||
let deferred = this.deactivatingDeferred[clientId] = Promise.defer();
|
||||
this.ril.getRadioInterface(clientId).deactivateDataCalls();
|
||||
return deferred.promise;
|
||||
}).bind(this);
|
||||
},
|
||||
|
||||
_createTimer: function() {
|
||||
if (!this.timer) {
|
||||
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
}
|
||||
this.timer.initWithCallback(this._executeRequest, RADIO_POWER_OFF_TIMEOUT,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
},
|
||||
|
||||
_cancelTimer: function() {
|
||||
if (this.timer) {
|
||||
this.timer.cancel();
|
||||
}
|
||||
},
|
||||
|
||||
_executeRequest: function() {
|
||||
if (typeof this.request === "function") {
|
||||
if (DEBUG) debug("setRadioEnabled: executeRequest");
|
||||
this._cancelTimer();
|
||||
this.request();
|
||||
this.request = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Initialize shared preference "ril.numRadioInterfaces" according to system
|
||||
// property.
|
||||
try {
|
||||
Services.prefs.setIntPref(kPrefRilNumRadioInterfaces, (function () {
|
||||
|
@ -532,6 +663,7 @@ CdmaIccInfo.prototype = {
|
|||
|
||||
function RadioInterfaceLayer() {
|
||||
gMessageManager.init(this);
|
||||
gRadioEnabledController.init(this);
|
||||
|
||||
let options = {
|
||||
debug: debugPref,
|
||||
|
@ -685,7 +817,7 @@ WorkerMessenger.prototype = {
|
|||
* An optional message object to send.
|
||||
* @param callback [optional]
|
||||
* An optional callback function which is called when worker replies
|
||||
* with an message containing a 'rilMessageToken' attribute of the
|
||||
* with an message containing a "rilMessageToken" attribute of the
|
||||
* same value we passed. This callback function accepts only one
|
||||
* parameter -- the reply from worker. It also returns a boolean
|
||||
* value true to keep current token-callback mapping and wait for
|
||||
|
@ -720,7 +852,7 @@ WorkerMessenger.prototype = {
|
|||
* @param rilMessageType
|
||||
* A text string for worker message type.
|
||||
* @param ipcType [optinal]
|
||||
* A text string for ipc message type. 'msg.name' if omitted.
|
||||
* A text string for ipc message type. "msg.name" if omitted.
|
||||
*
|
||||
* @TODO: Bug 815526 - deprecate RILContentHelper.
|
||||
*/
|
||||
|
@ -758,6 +890,7 @@ function RadioInterface(options) {
|
|||
|
||||
this.rilContext = {
|
||||
radioState: RIL.GECKO_RADIOSTATE_UNAVAILABLE,
|
||||
detailedRadioState: null,
|
||||
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
|
||||
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
|
||||
iccInfo: null,
|
||||
|
@ -792,10 +925,7 @@ function RadioInterface(options) {
|
|||
|
||||
this.operatorInfo = {};
|
||||
|
||||
// Read the 'ril.radio.disabled' setting in order to start with a known
|
||||
// value at boot time.
|
||||
let lock = gSettingsService.createLock();
|
||||
lock.get("ril.radio.disabled", this);
|
||||
|
||||
// Read preferred network type from the setting DB.
|
||||
lock.get("ril.radio.preferredNetworkType", this);
|
||||
|
@ -805,11 +935,11 @@ function RadioInterface(options) {
|
|||
lock.get("ril.data.enabled", this);
|
||||
lock.get("ril.data.apnSettings", this);
|
||||
|
||||
// Read the 'time.clock.automatic-update.enabled' setting to see if
|
||||
// Read the "time.clock.automatic-update.enabled" setting to see if
|
||||
// we need to adjust the system clock time by NITZ or SNTP.
|
||||
lock.get(kSettingsClockAutoUpdateEnabled, this);
|
||||
|
||||
// Read the 'time.timezone.automatic-update.enabled' setting to see if
|
||||
// Read the "time.timezone.automatic-update.enabled" setting to see if
|
||||
// we need to adjust the system timezone by NITZ.
|
||||
lock.get(kSettingsTimezoneAutoUpdateEnabled, this);
|
||||
|
||||
|
@ -836,11 +966,11 @@ function RadioInterface(options) {
|
|||
this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this);
|
||||
|
||||
this._sntp = new Sntp(this.setClockBySntp.bind(this),
|
||||
Services.prefs.getIntPref('network.sntp.maxRetryCount'),
|
||||
Services.prefs.getIntPref('network.sntp.refreshPeriod'),
|
||||
Services.prefs.getIntPref('network.sntp.timeout'),
|
||||
Services.prefs.getCharPref('network.sntp.pools').split(';'),
|
||||
Services.prefs.getIntPref('network.sntp.port'));
|
||||
Services.prefs.getIntPref("network.sntp.maxRetryCount"),
|
||||
Services.prefs.getIntPref("network.sntp.refreshPeriod"),
|
||||
Services.prefs.getIntPref("network.sntp.timeout"),
|
||||
Services.prefs.getCharPref("network.sntp.pools").split(";"),
|
||||
Services.prefs.getIntPref("network.sntp.port"));
|
||||
}
|
||||
|
||||
RadioInterface.prototype = {
|
||||
|
@ -863,11 +993,11 @@ RadioInterface.prototype = {
|
|||
|
||||
/**
|
||||
* A utility function to copy objects. The srcInfo may contain
|
||||
* 'rilMessageType', should ignore it.
|
||||
* "rilMessageType", should ignore it.
|
||||
*/
|
||||
updateInfo: function updateInfo(srcInfo, destInfo) {
|
||||
for (let key in srcInfo) {
|
||||
if (key === 'rilMessageType') {
|
||||
if (key === "rilMessageType") {
|
||||
continue;
|
||||
}
|
||||
destInfo[key] = srcInfo[key];
|
||||
|
@ -876,7 +1006,7 @@ RadioInterface.prototype = {
|
|||
|
||||
/**
|
||||
* A utility function to compare objects. The srcInfo may contain
|
||||
* 'rilMessageType', should ignore it.
|
||||
* "rilMessageType", should ignore it.
|
||||
*/
|
||||
isInfoChanged: function isInfoChanged(srcInfo, destInfo) {
|
||||
if (!destInfo) {
|
||||
|
@ -884,7 +1014,7 @@ RadioInterface.prototype = {
|
|||
}
|
||||
|
||||
for (let key in srcInfo) {
|
||||
if (key === 'rilMessageType') {
|
||||
if (key === "rilMessageType") {
|
||||
continue;
|
||||
}
|
||||
if (srcInfo[key] !== destInfo[key]) {
|
||||
|
@ -991,6 +1121,9 @@ RadioInterface.prototype = {
|
|||
case "RIL:ExitEmergencyCbMode":
|
||||
this.workerMessenger.sendWithIPCMessage(msg, "exitEmergencyCbMode");
|
||||
break;
|
||||
case "RIL:SetRadioEnabled":
|
||||
this.setRadioEnabled(msg.target, msg.json.data);
|
||||
break;
|
||||
case "RIL:GetVoicemailInfo":
|
||||
// This message is sync.
|
||||
return this.voicemailInfo;
|
||||
|
@ -1115,10 +1248,6 @@ RadioInterface.prototype = {
|
|||
case "stksessionend":
|
||||
gMessageManager.sendIccMessage("RIL:StkSessionEnd", this.clientId, null);
|
||||
break;
|
||||
case "setRadioEnabled":
|
||||
let lock = gSettingsService.createLock();
|
||||
lock.set("ril.radio.disabled", !message.on, null, null);
|
||||
break;
|
||||
case "exitEmergencyCbMode":
|
||||
this.handleExitEmergencyCbMode(message);
|
||||
break;
|
||||
|
@ -1481,71 +1610,44 @@ RadioInterface.prototype = {
|
|||
this.clientId, status);
|
||||
},
|
||||
|
||||
handleRadioStateChange: function handleRadioStateChange(message) {
|
||||
this._changingRadioPower = false;
|
||||
_isRadioChanging: function _isRadioChanging() {
|
||||
let state = this.rilContext.detailedRadioState;
|
||||
return state == RIL.GECKO_DETAILED_RADIOSTATE_ENABLING ||
|
||||
state == RIL.GECKO_DETAILED_RADIOSTATE_DISABLING;
|
||||
},
|
||||
|
||||
_convertRadioState: function _converRadioState(state) {
|
||||
switch (state) {
|
||||
case RIL.GECKO_RADIOSTATE_OFF:
|
||||
return RIL.GECKO_DETAILED_RADIOSTATE_DISABLED;
|
||||
case RIL.GECKO_RADIOSTATE_READY:
|
||||
return RIL.GECKO_DETAILED_RADIOSTATE_ENABLED;
|
||||
default:
|
||||
return RIL.GECKO_DETAILED_RADIOSTATE_UNKNOWN;
|
||||
}
|
||||
},
|
||||
|
||||
handleRadioStateChange: function handleRadioStateChange(message) {
|
||||
let newState = message.radioState;
|
||||
if (this.rilContext.radioState == newState) {
|
||||
return;
|
||||
}
|
||||
this.rilContext.radioState = newState;
|
||||
this.handleDetailedRadioStateChanged(this._convertRadioState(newState));
|
||||
|
||||
//TODO Should we notify this change as a card state change?
|
||||
|
||||
this._ensureRadioState();
|
||||
},
|
||||
|
||||
_ensureRadioState: function _ensureRadioState() {
|
||||
if (DEBUG) {
|
||||
this.debug("Reported radio state is " + this.rilContext.radioState +
|
||||
", desired radio enabled state is " + this._radioEnabled);
|
||||
}
|
||||
if (this._radioEnabled == null) {
|
||||
// We haven't read the initial value from the settings DB yet.
|
||||
// Wait for that.
|
||||
handleDetailedRadioStateChanged: function handleDetailedRadioStateChanged(state) {
|
||||
if (this.rilContext.detailedRadioState == state) {
|
||||
return;
|
||||
}
|
||||
if (!this._sysMsgListenerReady) {
|
||||
// The UI's system app isn't ready yet for us to receive any
|
||||
// events (e.g. incoming SMS, etc.). Wait for that.
|
||||
return;
|
||||
}
|
||||
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_UNKNOWN) {
|
||||
// We haven't received a radio state notification from the RIL
|
||||
// yet. Wait for that.
|
||||
return;
|
||||
}
|
||||
if (this._changingRadioPower) {
|
||||
// We're changing the radio power currently, ignore any changes.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_OFF &&
|
||||
this._radioEnabled) {
|
||||
this._changingRadioPower = true;
|
||||
this.setRadioEnabled(true);
|
||||
}
|
||||
if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_READY &&
|
||||
!this._radioEnabled) {
|
||||
this._changingRadioPower = true;
|
||||
this.powerOffRadioSafely();
|
||||
}
|
||||
this.rilContext.detailedRadioState = state;
|
||||
gMessageManager.sendMobileConnectionMessage("RIL:RadioStateChanged",
|
||||
this.clientId, state);
|
||||
},
|
||||
|
||||
_radioOffTimer: null,
|
||||
_cancelRadioOffTimer: function _cancelRadioOffTimer() {
|
||||
if (this._radioOffTimer) {
|
||||
this._radioOffTimer.cancel();
|
||||
}
|
||||
},
|
||||
_fireRadioOffTimer: function _fireRadioOffTimer() {
|
||||
if (DEBUG) this.debug("Radio off timer expired, set radio power off right away.");
|
||||
this.setRadioEnabled(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clean up all existing data calls before turning radio off.
|
||||
*/
|
||||
powerOffRadioSafely: function powerOffRadioSafely() {
|
||||
deactivateDataCalls: function deactivateDataCalls() {
|
||||
let dataDisconnecting = false;
|
||||
for each (let apnSetting in this.apnSettings.byApn) {
|
||||
for each (let type in apnSetting.types) {
|
||||
|
@ -1556,16 +1658,12 @@ RadioInterface.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (dataDisconnecting) {
|
||||
if (this._radioOffTimer == null) {
|
||||
this._radioOffTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
}
|
||||
this._radioOffTimer.initWithCallback(this._fireRadioOffTimer.bind(this),
|
||||
RADIO_POWER_OFF_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
this._radioOffAfterDataDisconnected = true;
|
||||
return;
|
||||
|
||||
// No data calls exist. It's safe to proceed the pending radio power off
|
||||
// request.
|
||||
if (gRadioEnabledController.isDeactivatingDataCalls() && !dataDisconnecting) {
|
||||
gRadioEnabledController.finishDeactivatingDataCalls(this.clientId);
|
||||
}
|
||||
this.setRadioEnabled(false);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1611,8 +1709,8 @@ RadioInterface.prototype = {
|
|||
// Combine APN, user name, and password as the key of |byApn| object to
|
||||
// refer to the corresponding APN setting.
|
||||
let apnKey = inputApnSetting.apn +
|
||||
(inputApnSetting.user || '') +
|
||||
(inputApnSetting.password || '');
|
||||
(inputApnSetting.user || "") +
|
||||
(inputApnSetting.password || "");
|
||||
|
||||
if (!this.apnSettings.byApn[apnKey]) {
|
||||
this.apnSettings.byApn[apnKey] = inputApnSetting;
|
||||
|
@ -1729,7 +1827,7 @@ RadioInterface.prototype = {
|
|||
if (DEBUG) this.debug("Don't connect data call when Wifi is connected.");
|
||||
return;
|
||||
}
|
||||
if (this._changingRadioPower) {
|
||||
if (this._isRadioChanging()) {
|
||||
// We're changing the radio power currently, ignore any changes.
|
||||
return;
|
||||
}
|
||||
|
@ -1936,7 +2034,7 @@ RadioInterface.prototype = {
|
|||
// At this point we could send a message to content to notify the user
|
||||
// that storing an incoming SMS failed, most likely due to a full disk.
|
||||
if (DEBUG) {
|
||||
this.debug("Could not store SMS, error code " + rv);
|
||||
this.debug("Could not store SMS " + message.id + ", error code " + rv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1946,8 +2044,8 @@ RadioInterface.prototype = {
|
|||
}.bind(this);
|
||||
|
||||
if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
|
||||
gMobileMessageDatabaseService.saveReceivedMessage(message,
|
||||
notifyReceived);
|
||||
message.id = gMobileMessageDatabaseService.saveReceivedMessage(message,
|
||||
notifyReceived);
|
||||
} else {
|
||||
message.id = -1;
|
||||
message.threadId = 0;
|
||||
|
@ -2005,7 +2103,7 @@ RadioInterface.prototype = {
|
|||
// Process pending radio power off request after all data calls
|
||||
// are disconnected.
|
||||
if (datacall.state == RIL.GECKO_NETWORK_STATE_UNKNOWN &&
|
||||
this._radioOffAfterDataDisconnected) {
|
||||
gRadioEnabledController.isDeactivatingDataCalls()) {
|
||||
let anyDataConnected = false;
|
||||
for each (let apnSetting in this.apnSettings.byApn) {
|
||||
for each (let type in apnSetting.types) {
|
||||
|
@ -2019,10 +2117,8 @@ RadioInterface.prototype = {
|
|||
}
|
||||
}
|
||||
if (!anyDataConnected) {
|
||||
if (DEBUG) this.debug("All data connections are disconnected, set radio off.");
|
||||
this._radioOffAfterDataDisconnected = false;
|
||||
this._cancelRadioOffTimer();
|
||||
this.setRadioEnabled(false);
|
||||
if (DEBUG) this.debug("All data connections are disconnected.");
|
||||
gRadioEnabledController.finishDeactivatingDataCalls(this.clientId);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2215,9 +2311,7 @@ RadioInterface.prototype = {
|
|||
observe: function observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case kSysMsgListenerReadyObserverTopic:
|
||||
Services.obs.removeObserver(this, kSysMsgListenerReadyObserverTopic);
|
||||
this._sysMsgListenerReady = true;
|
||||
this._ensureRadioState();
|
||||
this.setRadioEnabledInternal({enabled: true}, null);
|
||||
break;
|
||||
case kMozSettingsChangedObserverTopic:
|
||||
let setting = JSON.parse(data);
|
||||
|
@ -2272,33 +2366,17 @@ RadioInterface.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// Flag to determine whether the UI's system app is ready to receive
|
||||
// events yet.
|
||||
_sysMsgListenerReady: false,
|
||||
|
||||
// Flag to determine the radio state to start with when we boot up. It
|
||||
// corresponds to the 'ril.radio.disabled' setting from the UI.
|
||||
_radioEnabled: null,
|
||||
|
||||
// Flag to ignore any radio power change requests during We're changing
|
||||
// the radio power.
|
||||
_changingRadioPower: false,
|
||||
|
||||
// Flag to determine if we need to set radio off when we are notified a data
|
||||
// call has been disconnected.
|
||||
_radioOffAfterDataDisconnected: false,
|
||||
|
||||
// Data calls setting.
|
||||
dataCallSettings: null,
|
||||
|
||||
apnSettings: null,
|
||||
|
||||
// Flag to determine whether to update system clock automatically. It
|
||||
// corresponds to the 'time.clock.automatic-update.enabled' setting.
|
||||
// corresponds to the "time.clock.automatic-update.enabled" setting.
|
||||
_clockAutoUpdateEnabled: null,
|
||||
|
||||
// Flag to determine whether to update system timezone automatically. It
|
||||
// corresponds to the 'time.clock.automatic-update.enabled' setting.
|
||||
// corresponds to the "time.clock.automatic-update.enabled" setting.
|
||||
_timezoneAutoUpdateEnabled: null,
|
||||
|
||||
// Remember the last NITZ message so that we can set the time based on
|
||||
|
@ -2346,11 +2424,6 @@ RadioInterface.prototype = {
|
|||
// nsISettingsServiceCallback
|
||||
handle: function handle(aName, aResult) {
|
||||
switch(aName) {
|
||||
case "ril.radio.disabled":
|
||||
if (DEBUG) this.debug("'ril.radio.disabled' is now " + aResult);
|
||||
this._radioEnabled = !aResult;
|
||||
this._ensureRadioState();
|
||||
break;
|
||||
case "ril.radio.preferredNetworkType":
|
||||
if (DEBUG) this.debug("'ril.radio.preferredNetworkType' is now " + aResult);
|
||||
this.setPreferredNetworkType(aResult);
|
||||
|
@ -2422,10 +2495,6 @@ RadioInterface.prototype = {
|
|||
handleError: function handleError(aErrorMessage) {
|
||||
if (DEBUG) this.debug("There was an error while reading RIL settings.");
|
||||
|
||||
// Default radio to on.
|
||||
this._radioEnabled = true;
|
||||
this._ensureRadioState();
|
||||
|
||||
// Clean data call setting.
|
||||
this.dataCallSettings.oldEnabled = false;
|
||||
this.dataCallSettings.enabled = false;
|
||||
|
@ -2438,11 +2507,6 @@ RadioInterface.prototype = {
|
|||
|
||||
// nsIRadioInterface
|
||||
|
||||
setRadioEnabled: function setRadioEnabled(value) {
|
||||
if (DEBUG) this.debug("Setting radio power to " + value);
|
||||
this.workerMessenger.send("setRadioPower", { on: value });
|
||||
},
|
||||
|
||||
rilContext: null,
|
||||
|
||||
// Handle phone functions of nsIRILContentHelper
|
||||
|
@ -2510,6 +2574,62 @@ RadioInterface.prototype = {
|
|||
}).bind(this));
|
||||
},
|
||||
|
||||
isValidStateForSetRadioEnabled: function() {
|
||||
let state = this.rilContext.radioState;
|
||||
|
||||
return !this._isRadioChanging() &&
|
||||
(state == RIL.GECKO_RADIOSTATE_READY ||
|
||||
state == RIL.GECKO_RADIOSTATE_OFF);
|
||||
},
|
||||
|
||||
isDummyForSetRadioEnabled: function(message) {
|
||||
let state = this.rilContext.radioState;
|
||||
|
||||
return (state == RIL.GECKO_RADIOSTATE_READY && message.enabled) ||
|
||||
(state == RIL.GECKO_RADIOSTATE_OFF && !message.enabled);
|
||||
},
|
||||
|
||||
setRadioEnabledResponse: function(target, message, errorMsg) {
|
||||
if (errorMsg) {
|
||||
message.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
target.sendAsyncMessage("RIL:SetRadioEnabled", {
|
||||
clientId: this.clientId,
|
||||
data: message
|
||||
});
|
||||
},
|
||||
|
||||
setRadioEnabled: function setRadioEnabled(target, message) {
|
||||
if (DEBUG) {
|
||||
this.debug("setRadioEnabled: " + JSON.stringify(message));
|
||||
}
|
||||
|
||||
if (!this.isValidStateForSetRadioEnabled()) {
|
||||
this.setRadioEnabledResponse(target, message, "InvalidStateError");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDummyForSetRadioEnabled(message)) {
|
||||
this.setRadioEnabledResponse(target, message);
|
||||
return;
|
||||
}
|
||||
|
||||
let callback = (function(response) {
|
||||
this.setRadioEnabledResponse(target, response);
|
||||
return false;
|
||||
}).bind(this);
|
||||
|
||||
this.setRadioEnabledInternal(message, callback);
|
||||
},
|
||||
|
||||
setRadioEnabledInternal: function setRadioEnabledInternal(message, callback) {
|
||||
let state = message.enabled ? RIL.GECKO_DETAILED_RADIOSTATE_ENABLING
|
||||
: RIL.GECKO_DETAILED_RADIOSTATE_DISABLING;
|
||||
this.handleDetailedRadioStateChanged(state);
|
||||
this.workerMessenger.send("setRadioEnabled", message, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* List of tuples of national language identifier pairs.
|
||||
*
|
||||
|
@ -2586,7 +2706,7 @@ RadioInterface.prototype = {
|
|||
|
||||
// Bug 816082, when strict7BitEncoding is enabled, we should replace
|
||||
// characters that can't be encoded with GSM 7-Bit alphabets with '*'.
|
||||
c = '*';
|
||||
c = "*";
|
||||
if (langTable.indexOf(c) >= 0) {
|
||||
length++;
|
||||
} else if (langShiftTable.indexOf(c) >= 0) {
|
||||
|
@ -2808,7 +2928,7 @@ RadioInterface.prototype = {
|
|||
|
||||
// Bug 816082, when strict7BitEncoding is enabled, we should replace
|
||||
// characters that can't be encoded with GSM 7-Bit alphabets with '*'.
|
||||
c = '*';
|
||||
c = "*";
|
||||
if (langTable.indexOf(c) >= 0) {
|
||||
inc = 1;
|
||||
}
|
||||
|
@ -2978,7 +3098,8 @@ RadioInterface.prototype = {
|
|||
if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " +
|
||||
options.number);
|
||||
errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
|
||||
} else if (!this._radioEnabled) {
|
||||
} else if (this.rilContext.detailedRadioState ==
|
||||
RIL.GECKO_DETAILED_RADIOSTATE_DISABLED) {
|
||||
if (DEBUG) this.debug("Error! Radio is disabled when sending SMS.");
|
||||
errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
|
||||
} else if (this.rilContext.cardState != "ready") {
|
||||
|
@ -3063,7 +3184,7 @@ RadioInterface.prototype = {
|
|||
? kSmsDeliverySuccessObserverTopic
|
||||
: kSmsDeliveryErrorObserverTopic;
|
||||
|
||||
// Broadcasting a 'sms-delivery-success' system message to open apps.
|
||||
// Broadcasting a "sms-delivery-success" system message to open apps.
|
||||
if (topic == kSmsDeliverySuccessObserverTopic) {
|
||||
this.broadcastSmsSystemMessage(topic, domMessage);
|
||||
}
|
||||
|
@ -3152,8 +3273,8 @@ RadioInterface.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
gMobileMessageDatabaseService.saveSendingMessage(sendingMessage,
|
||||
notifyResult);
|
||||
let id = gMobileMessageDatabaseService.saveSendingMessage(
|
||||
sendingMessage, notifyResult);
|
||||
},
|
||||
|
||||
registerDataCallCallback: function registerDataCallCallback(callback) {
|
||||
|
@ -3393,11 +3514,11 @@ RILNetworkInterface.prototype = {
|
|||
dns2: null,
|
||||
|
||||
get httpProxyHost() {
|
||||
return this.apnSetting.proxy || '';
|
||||
return this.apnSetting.proxy || "";
|
||||
},
|
||||
|
||||
get httpProxyPort() {
|
||||
return this.apnSetting.port || '';
|
||||
return this.apnSetting.port || "";
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3525,7 +3646,7 @@ RILNetworkInterface.prototype = {
|
|||
}
|
||||
|
||||
if (this.state == datacall.state) {
|
||||
if (datacall.state != GECKO_NETWORK_STATE_CONNECTED) {
|
||||
if (datacall.state != RIL.GECKO_NETWORK_STATE_CONNECTED) {
|
||||
return;
|
||||
}
|
||||
// State remains connected, check for minor changes.
|
||||
|
|
|
@ -2379,6 +2379,12 @@ this.GECKO_RADIOSTATE_UNAVAILABLE = null;
|
|||
this.GECKO_RADIOSTATE_OFF = "off";
|
||||
this.GECKO_RADIOSTATE_READY = "ready";
|
||||
|
||||
this.GECKO_DETAILED_RADIOSTATE_UNKNOWN = null;
|
||||
this.GECKO_DETAILED_RADIOSTATE_ENABLING = "enabling";
|
||||
this.GECKO_DETAILED_RADIOSTATE_ENABLED = "enabled";
|
||||
this.GECKO_DETAILED_RADIOSTATE_DISABLING = "disabling";
|
||||
this.GECKO_DETAILED_RADIOSTATE_DISABLED = "disabled";
|
||||
|
||||
this.GECKO_CARDSTATE_UNDETECTED = null;
|
||||
this.GECKO_CARDSTATE_ILLEGAL = "illegal";
|
||||
this.GECKO_CARDSTATE_UNKNOWN = "unknown";
|
||||
|
|
|
@ -944,15 +944,15 @@ let RIL = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Request the phone's radio power to be switched on or off.
|
||||
* Request the phone's radio to be enabled or disabled.
|
||||
*
|
||||
* @param on
|
||||
* Boolean indicating the desired power state.
|
||||
* @param enabled
|
||||
* Boolean indicating the desired state.
|
||||
*/
|
||||
setRadioPower: function setRadioPower(options) {
|
||||
setRadioEnabled: function setRadioEnabled(options) {
|
||||
Buf.newParcel(REQUEST_RADIO_POWER, options);
|
||||
Buf.writeInt32(1);
|
||||
Buf.writeInt32(options.on ? 1 : 0);
|
||||
Buf.writeInt32(options.enabled ? 1 : 0);
|
||||
Buf.sendParcel();
|
||||
},
|
||||
|
||||
|
@ -1413,9 +1413,7 @@ let RIL = {
|
|||
}
|
||||
this.cachedDialRequest.onerror = onerror;
|
||||
this.cachedDialRequest.callback = this.sendDialRequest.bind(this, options);
|
||||
|
||||
// Change radio setting value in settings DB to enable radio.
|
||||
this.sendChromeMessage({rilMessageType: "setRadioEnabled", on: true});
|
||||
this.setRadioEnabled({enabled: true});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5184,18 +5182,25 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
|
|||
this._processOperator(operatorData);
|
||||
};
|
||||
RIL[REQUEST_RADIO_POWER] = function REQUEST_RADIO_POWER(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
if (this.cachedDialRequest && options.on) {
|
||||
// Turning on radio fails. Notify the error of making an emergency call.
|
||||
this.cachedDialRequest.onerror(GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
this.cachedDialRequest = null;
|
||||
if (options.rilMessageType == null) {
|
||||
// The request was made by ril_worker itself.
|
||||
if (options.rilRequestError) {
|
||||
if (this.cachedDialRequest && options.enabled) {
|
||||
// Turning on radio fails. Notify the error of making an emergency call.
|
||||
this.cachedDialRequest.onerror(GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
this.cachedDialRequest = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isInitialRadioState) {
|
||||
this._isInitialRadioState = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isInitialRadioState) {
|
||||
this._isInitialRadioState = false;
|
||||
}
|
||||
this.sendChromeMessage(options);
|
||||
};
|
||||
RIL[REQUEST_DTMF] = null;
|
||||
RIL[REQUEST_SEND_SMS] = function REQUEST_SEND_SMS(length, options) {
|
||||
|
@ -6020,7 +6025,7 @@ RIL[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RA
|
|||
if (this._isInitialRadioState) {
|
||||
// Even radioState is RADIO_STATE_OFF, we still have to maually turn radio off,
|
||||
// otherwise REQUEST_GET_SIM_STATUS will still report CARD_STATE_PRESENT.
|
||||
this.setRadioPower({on: false});
|
||||
this.setRadioEnabled({enabled: false});
|
||||
}
|
||||
|
||||
let newState;
|
||||
|
|
Загрузка…
Ссылка в новой задаче