Bug 777057 - MobileConnection: expose whether or not the radio is searching. r=marshall_law sr=sicking

This commit is contained in:
Philipp von Weitershausen 2012-08-07 12:11:48 -07:00
parent 0623ad4e5e
commit da6f5f6d44
8 changed files with 280 additions and 142 deletions

View File

@ -222,11 +222,19 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
attribute nsIDOMEventListener onussdreceived;
};
[scriptable, uuid(46321d6e-bbce-4b7b-aa32-d17b6aa984fe)]
[scriptable, uuid(6601c20e-337f-4286-8d6e-0990fc1c2372)]
interface nsIDOMMozMobileConnectionInfo : nsISupports
{
/**
* Indicates whether the device is connected to a mobile network.
* State of the connection.
*
* Possible values: 'notSearching', 'searching', 'denied', 'registered'.
* null if the state is unknown.
*/
readonly attribute DOMString state;
/**
* Indicates whether the connection is ready. This may be different
*/
readonly attribute bool connected;

View File

@ -3,3 +3,8 @@
b2g = true
browser = false
qemu = true
[test_mobile_voice_state.js]
b2g = true
browser = false
qemu = true

View File

@ -1,6 +1,5 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// getNetworks() can take some time..
MARIONETTE_TIMEOUT = 60000;
@ -35,15 +34,17 @@ function isTelkilaNetwork(network) {
function testConnectionInfo() {
let voice = connection.voice;
is(voice.connected, true);
is(voice.state, "registered");
is(voice.emergencyCallsOnly, false);
is(voice.roaming, false);
isAndroidNetwork(voice.network);
let data = connection.data;
// TODO Bug 762959: enable these checks when data state updates are implemented
// is(data.connected, true);
// is(data.emergencyCallsOnly, false);
// is(data.roaming, false);
// data.connected = true means there's an active data call which we
// can't predict here.
is(data.state, "registered");
is(data.emergencyCallsOnly, false);
is(data.roaming, false);
isAndroidNetwork(data.network);
testGetNetworks();

View File

@ -0,0 +1,115 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
const WHITELIST_PREF = "dom.mobileconnection.whitelist";
let uriPrePath = window.location.protocol + "//" + window.location.host;
SpecialPowers.setCharPref(WHITELIST_PREF, uriPrePath);
let connection = navigator.mozMobileConnection;
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);
function setEmulatorVoiceState(state) {
runEmulatorCmd("gsm voice " + state, function (result) {
is(result[0], "OK");
});
}
function testConnectionInfo() {
let voice = connection.voice;
is(voice.connected, true);
is(voice.state, "registered");
is(voice.emergencyCallsOnly, false);
is(voice.roaming, false);
testUnregistered();
}
function testUnregistered() {
setEmulatorVoiceState("unregistered");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "notSearching");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
testSearching();
});
}
function testSearching() {
// For some reason, requesting the "searching" state puts the fake modem
// into "registered"... Skipping this test for now.
testDenied();
return;
setEmulatorVoiceState("searching");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "searching");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
testDenied();
});
}
function testDenied() {
setEmulatorVoiceState("denied");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, false);
is(connection.voice.state, "denied");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
testRoaming();
});
}
function testRoaming() {
setEmulatorVoiceState("roaming");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, true);
is(connection.voice.state, "registered");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, true);
testHome();
});
}
function testHome() {
setEmulatorVoiceState("home");
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(connection.voice.connected, true);
is(connection.voice.state, "registered");
is(connection.voice.emergencyCallsOnly, false);
is(connection.voice.roaming, false);
cleanUp();
});
}
function cleanUp() {
SpecialPowers.clearUserPref(WHITELIST_PREF);
finish();
}
testConnectionInfo();

View File

@ -85,6 +85,7 @@ MobileConnectionInfo.prototype = {
// nsIDOMMozMobileConnectionInfo
connected: false,
state: null,
emergencyCallsOnly: false,
roaming: false,
network: null,

View File

@ -446,36 +446,32 @@ RadioInterfaceLayer.prototype = {
let selectionMessage = message[RIL.NETWORK_INFO_NETWORK_SELECTION_MODE];
// Batch the *InfoChanged messages together
let voiceInfoChanged = false;
if (voiceMessage) {
voiceMessage.batch = true;
voiceInfoChanged = this.updateVoiceConnection(voiceMessage);
this.updateVoiceConnection(voiceMessage);
}
let dataInfoChanged = false;
if (dataMessage) {
dataMessage.batch = true;
dataInfoChanged = this.updateDataConnection(dataMessage);
this.updateDataConnection(dataMessage);
}
let voice = this.rilContext.voice;
let data = this.rilContext.data;
if (operatorMessage) {
if (this.networkChanged(operatorMessage, voice.network)) {
voiceInfoChanged = true;
voice.network = operatorMessage;
}
if (this.networkChanged(operatorMessage, data.network)) {
dataInfoChanged = true;
data.network = operatorMessage;
}
}
if (voiceInfoChanged) {
if (voiceMessage || operatorMessage) {
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voice);
}
if (dataInfoChanged) {
if (dataMessage || operatorMessage) {
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
}
@ -488,96 +484,88 @@ RadioInterfaceLayer.prototype = {
* Sends the RIL:VoiceInfoChanged message when the voice
* connection's state has changed.
*
* @param state The new voice connection state. When state.batch is true,
* the RIL:VoiceInfoChanged message will not be sent.
* @return Whether or not this.radioState.voice was updated
* @param newInfo The new voice connection information. When newInfo.batch is true,
* the RIL:VoiceInfoChanged message will not be sent.
*/
updateVoiceConnection: function updateVoiceConnection(state) {
updateVoiceConnection: function updateVoiceConnection(newInfo) {
let voiceInfo = this.rilContext.voice;
let regState = state.regState;
voiceInfo.type = "gsm"; //TODO see bug 726098.
if (!state || regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
voiceInfo.connected = false;
voiceInfo.emergencyCallsOnly = false;
voiceInfo.roaming = false;
voiceInfo.state = newInfo.state;
voiceInfo.connected = newInfo.connected;
voiceInfo.roaming = newInfo.roaming;
voiceInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
// Unlike the data registration info, the voice info typically contains
// no (useful) radio tech information, so we have to manually set
// this here. (TODO GSM only for now, see bug 726098.)
voiceInfo.type = "gsm";
// Make sure we also reset the operator and signal strength information
// if we drop off the network.
if (newInfo.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
voiceInfo.network = null;
voiceInfo.type = null;
voiceInfo.signalStrength = null;
voiceInfo.relSignalStrength = null;
}
if (!newInfo.batch) {
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
return false;
}
let isRoaming = regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING;
let isHome = regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME;
let isConnected = isRoaming || isHome;
let radioTech = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
// Ensure that we check for changes before sending the message
if (voiceInfo.emergencyCallsOnly != state.emergencyCallsOnly ||
voiceInfo.connected != isConnected ||
voiceInfo.roaming != isRoaming ||
voiceInfo.type != radioTech) {
voiceInfo.emergencyCallsOnly = state.emergencyCallsOnly;
voiceInfo.connected = isConnected;
voiceInfo.roaming = isRoaming;
voiceInfo.type = radioTech;
// When batch is true, hold off on firing VoiceInfoChanged events
if (!state.batch) {
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
}
return true;
}
return false;
},
updateDataConnection: function updateDataConnection(state) {
let data = this.rilContext.data;
if (!state || state.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
data.connected = false;
data.emergencyCallsOnly = false;
data.roaming = false;
data.network = null;
data.type = null;
data.signalStrength = null;
data.relSignalStrength = null;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
return false;
updateDataConnection: function updateDataConnection(newInfo) {
let dataInfo = this.rilContext.data;
dataInfo.state = newInfo.state;
dataInfo.roaming = newInfo.roaming;
dataInfo.emergencyCallsOnly = newInfo.emergencyCallsOnly;
dataInfo.type = newInfo.type;
// For the data connection, the `connected` flag indicates whether
// there's an active data call.
dataInfo.connected = RILNetworkInterface.connected;
// Make sure we also reset the operator and signal strength information
// if we drop off the network.
if (newInfo.regState == RIL.NETWORK_CREG_STATE_UNKNOWN) {
dataInfo.network = null;
dataInfo.signalStrength = null;
dataInfo.relSignalStrength = null;
}
if (!newInfo.batch) {
ppmm.sendAsyncMessage("RIL:DataInfoChanged", dataInfo);
}
data.roaming =
(state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
if (!this.dataCallSettings["enabled"]) {
return false;
return;
}
let isRegistered =
state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME ||
(this.dataCallSettings["roaming_enabled"] &&
state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
newInfo.state == RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED &&
(!newInfo.roaming || this._isDataRoamingEnabled());
let haveDataConnection =
state.radioTech != RIL.NETWORK_CREG_TECH_UNKNOWN;
newInfo.type != GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
if (isRegistered && haveDataConnection) {
debug("Radio is ready for data connection.");
this.updateRILNetworkInterface();
}
return false;
},
handleSignalStrengthChange: function handleSignalStrengthChange(message) {
let voiceInfo = this.rilContext.voice;
// TODO CDMA, EVDO, LTE, etc. (see bug 726098)
this.rilContext.voice.signalStrength = message.gsmDBM;
this.rilContext.voice.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", this.rilContext.voice);
if (voiceInfo.signalStrength != message.gsmDBM ||
voiceInfo.relSignalStrength != message.gsmRelative) {
voiceInfo.signalStrength = message.gsmDBM;
voiceInfo.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
}
this.rilContext.data.signalStrength = message.gsmDBM;
this.rilContext.data.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", this.rilContext.data);
let dataInfo = this.rilContext.data;
if (dataInfo.signalStrength != message.gsmDBM ||
dataInfo.relSignalStrength != message.gsmRelative) {
dataInfo.signalStrength = message.gsmDBM;
dataInfo.relSignalStrength = message.gsmRelative;
ppmm.sendAsyncMessage("RIL:DataInfoChanged", dataInfo);
}
},
networkChanged: function networkChanged(srcNetwork, destNetwork) {

View File

@ -1449,6 +1449,25 @@ const GECKO_NETWORK_SELECTION_UNKNOWN = null;
const GECKO_NETWORK_SELECTION_AUTOMATIC = "automatic";
const GECKO_NETWORK_SELECTION_MANUAL = "manual";
const GECKO_MOBILE_CONNECTION_STATE_UNKNOWN = null;
const GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING = "notSearching";
const GECKO_MOBILE_CONNECTION_STATE_SEARCHING = "searching";
const GECKO_MOBILE_CONNECTION_STATE_REGISTERED = "registered";
const GECKO_MOBILE_CONNECTION_STATE_DENIED = "denied";
const NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE = {};
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_NOT_SEARCHING] = GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_REGISTERED_HOME] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_SEARCHING] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_DENIED] = GECKO_MOBILE_CONNECTION_STATE_DENIED;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_REGISTERED_ROAMING] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_SEARCHING;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_DENIED_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_DENIED;
NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
const GECKO_CALL_ERROR_BAD_NUMBER = "BadNumberError";
const GECKO_CALL_ERROR_NORMAL_CALL_CLEARING = "NormalCallClearingError";
const GECKO_CALL_ERROR_BUSY = "BusyError";

View File

@ -62,6 +62,9 @@ let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = false;
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = false;
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = false;
// Marker object.
let PENDING_NETWORK_TYPE = {};
/**
* This object contains helpers buffering incoming data & deconstructing it
* into parcels as well as buffering outgoing data & constructing parcels.
@ -615,6 +618,8 @@ let RIL = {
*/
aid: null,
networkSelectionMode: null,
voiceRegistrationState: {},
dataRegistrationState: {},
@ -1504,10 +1509,7 @@ let RIL = {
*/
requestNetworkInfo: function requestNetworkInfo() {
if (this._processingNetworkInfo) {
if (DEBUG) {
debug("Already requesting network info: " +
JSON.stringify(this._pendingNetworkInfo));
}
if (DEBUG) debug("Network info requested, but we're already requesting network info.");
return;
}
@ -2172,19 +2174,21 @@ let RIL = {
return;
}
if (DEBUG) debug("Queuing " + type + " network info message: " + JSON.stringify(message));
this._pendingNetworkInfo[type] = message;
},
_receivedNetworkInfo: function _receivedNetworkInfo(type) {
if (DEBUG) debug("Received " + type + " network info.");
if (!this._processingNetworkInfo) {
return;
}
let pending = this._pendingNetworkInfo;
// We still need to track states for events that aren't fired
// We still need to track states for events that aren't fired.
if (!(type in pending)) {
pending[type] = true;
pending[type] = PENDING_NETWORK_TYPE;
}
// Pending network info is ready to be sent when no more messages
@ -2192,58 +2196,77 @@ let RIL = {
for (let i = 0; i < NETWORK_INFO_MESSAGE_TYPES.length; i++) {
let type = NETWORK_INFO_MESSAGE_TYPES[i];
if (!(type in pending)) {
if (DEBUG) debug("Still missing some more network info, not notifying main thread.");
return;
}
}
// Do a pass to clean up the processed messages that didn't create
// a response message, so we don't have unused keys in the outbound
// networkinfochanged message
let keys = Object.keys(pending);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
if (pending[key] === true) {
// networkinfochanged message.
for (let key in pending) {
if (pending[key] == PENDING_NETWORK_TYPE) {
delete pending[key];
}
}
if (DEBUG) debug("All pending network info has been received: " + JSON.stringify(pending));
// Send the message on the next tick of the worker's loop, so we give the
// last message a chance to call _sendNetworkInfoMessage first.
setTimeout(this._sendPendingNetworkInfo.bind(this), 0);
setTimeout(this._sendPendingNetworkInfo, 0);
},
_sendPendingNetworkInfo: function _sendPendingNetworkInfo() {
this.sendDOMMessage(this._pendingNetworkInfo);
RIL.sendDOMMessage(RIL._pendingNetworkInfo);
this._processingNetworkInfo = false;
RIL._processingNetworkInfo = false;
for (let i = 0; i < NETWORK_INFO_MESSAGE_TYPES.length; i++) {
delete this._pendingNetworkInfo[NETWORK_INFO_MESSAGE_TYPES[i]];
delete RIL._pendingNetworkInfo[NETWORK_INFO_MESSAGE_TYPES[i]];
}
},
/**
* Process the network registration flags.
*
* @return true if the state changed, false otherwise.
*/
_processCREG: function _processCREG(curState, newState) {
let changed = false;
let regState = RIL.parseInt(newState[0], NETWORK_CREG_STATE_UNKNOWN);
if (curState.regState != regState) {
changed = true;
curState.regState = regState;
curState.state = NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[regState];
curState.connected = regState == NETWORK_CREG_STATE_REGISTERED_HOME ||
regState == NETWORK_CREG_STATE_REGISTERED_ROAMING;
curState.roaming = regState == NETWORK_CREG_STATE_REGISTERED_ROAMING;
curState.emergencyCallsOnly =
(regState >= NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS) &&
(regState <= NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS);
if (RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE) {
curState.emergencyCallsOnly = !curState.connected;
}
}
let radioTech = RIL.parseInt(newState[3], NETWORK_CREG_TECH_UNKNOWN);
if (curState.radioTech != radioTech) {
changed = true;
curState.radioTech = radioTech;
curState.type = GECKO_RADIO_TECH[radioTech] || null;
}
return changed;
},
_processVoiceRegistrationState: function _processVoiceRegistrationState(state) {
this.initRILQuirks();
let rs = this.voiceRegistrationState;
let stateChanged = false;
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
if (rs.regState != regState) {
rs.regState = regState;
if (RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE) {
rs.emergencyCallsOnly =
(regState != NETWORK_CREG_STATE_REGISTERED_HOME) &&
(regState != NETWORK_CREG_STATE_REGISTERED_ROAMING);
} else {
rs.emergencyCallsOnly =
(regState >= NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS) &&
(regState <= NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS);
}
stateChanged = true;
if (regState == NETWORK_CREG_STATE_REGISTERED_HOME ||
regState == NETWORK_CREG_STATE_REGISTERED_ROAMING) {
RIL.getSMSCAddress();
}
let stateChanged = this._processCREG(rs, state);
if (stateChanged && rs.connected) {
RIL.getSMSCAddress();
}
let cell = this.cellLocation;
@ -2268,12 +2291,6 @@ let RIL = {
this.sendDOMMessage(cell);
}
let radioTech = RIL.parseInt(state[3], NETWORK_CREG_TECH_UNKNOWN);
if (rs.radioTech != radioTech) {
rs.radioTech = radioTech;
stateChanged = true;
}
// TODO: This zombie code branch that will be raised from the dead once
// we add explicit CDMA support everywhere (bug 726098).
let cdma = false;
@ -2301,20 +2318,7 @@ let RIL = {
_processDataRegistrationState: function _processDataRegistrationState(state) {
let rs = this.dataRegistrationState;
let stateChanged = false;
let regState = RIL.parseInt(state[0], NETWORK_CREG_STATE_UNKNOWN);
if (rs.regState != regState) {
rs.regState = regState;
stateChanged = true;
}
let radioTech = RIL.parseInt(state[3], NETWORK_CREG_TECH_UNKNOWN);
if (rs.radioTech != radioTech) {
rs.radioTech = radioTech;
stateChanged = true;
}
let stateChanged = this._processCREG(rs, state);
if (stateChanged) {
rs.rilMessageType = "dataregistrationstatechange";
this._sendNetworkInfoMessage(NETWORK_INFO_DATA_REGISTRATION_STATE, rs);
@ -2333,7 +2337,7 @@ let RIL = {
}
let [longName, shortName, networkTuple] = operatorData;
let thisTuple = String(this.operator.mcc) + this.operator.mnc;
let thisTuple = "" + this.operator.mcc + this.operator.mnc;
if (this.operator.longName !== longName ||
this.operator.shortName !== shortName ||
@ -3180,11 +3184,8 @@ RIL[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
}
let operatorData = Buf.readStringList();
if (DEBUG) debug("operator: " + operatorData);
if (DEBUG) debug("Operator: " + operatorData);
this._processOperator(operatorData);
};
RIL[REQUEST_RADIO_POWER] = null;
RIL[REQUEST_DTMF] = null;
@ -3383,8 +3384,8 @@ RIL[REQUEST_QUERY_NETWORK_SELECTION_MODE] = function REQUEST_QUERY_NETWORK_SELEC
break;
}
if (this.mode != selectionMode) {
this.mode = options.mode = selectionMode;
if (this.networkSelectionMode != selectionMode) {
this.networkSelectionMode = options.mode = selectionMode;
options.rilMessageType = "networkselectionmodechange";
this._sendNetworkInfoMessage(NETWORK_INFO_NETWORK_SELECTION_MODE, options);
}