Bug 856553 - Part 4: Add setRadioEnabled API (ril). r=hsinyi

This commit is contained in:
Szu-Yu Chen [:aknow] 2013-11-21 09:09:14 -05:00
Родитель d63e9055db
Коммит 5b8c158332
4 изменённых файлов: 324 добавлений и 155 удалений

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

@ -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;