michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: const {Cc: Cc, Ci: Ci, Cr: Cr, Cu: Cu} = SpecialPowers; michael@0: michael@0: const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled"; michael@0: const SETTINGS_KEY_DATA_ROAMING_ENABLED = "ril.data.roaming_enabled"; michael@0: const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings"; michael@0: michael@0: let Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise; michael@0: michael@0: let _pendingEmulatorCmdCount = 0; michael@0: michael@0: /** michael@0: * Send emulator command with safe guard. michael@0: * michael@0: * We should only call |finish()| after all emulator command transactions michael@0: * end, so here comes with the pending counter. Resolve when the emulator michael@0: * gives positive response, and reject otherwise. michael@0: * michael@0: * Fulfill params: michael@0: * result -- an array of emulator response lines. michael@0: * Reject params: michael@0: * result -- an array of emulator response lines. michael@0: * michael@0: * @param aCommand michael@0: * A string command to be passed to emulator through its telnet console. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function runEmulatorCmdSafe(aCommand) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: ++_pendingEmulatorCmdCount; michael@0: runEmulatorCmd(aCommand, function(aResult) { michael@0: --_pendingEmulatorCmdCount; michael@0: michael@0: ok(true, "Emulator response: " + JSON.stringify(aResult)); michael@0: if (Array.isArray(aResult) && michael@0: aResult[aResult.length - 1] === "OK") { michael@0: deferred.resolve(aResult); michael@0: } else { michael@0: deferred.reject(aResult); michael@0: } michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: /** michael@0: * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject. michael@0: * michael@0: * Fulfill params: A DOMEvent. michael@0: * Reject params: A DOMEvent. michael@0: * michael@0: * @param aRequest michael@0: * A DOMRequest instance. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function wrapDomRequestAsPromise(aRequest) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: ok(aRequest instanceof DOMRequest, michael@0: "aRequest is instanceof " + aRequest.constructor); michael@0: michael@0: aRequest.addEventListener("success", function(aEvent) { michael@0: deferred.resolve(aEvent); michael@0: }); michael@0: aRequest.addEventListener("error", function(aEvent) { michael@0: deferred.reject(aEvent); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: let workingFrame; michael@0: michael@0: /** michael@0: * Get mozSettings value specified by @aKey. michael@0: * michael@0: * Resolve if that mozSettings value is retrieved successfully, reject michael@0: * otherwise. michael@0: * michael@0: * Fulfill params: michael@0: * The corresponding mozSettings value of the key. michael@0: * Reject params: (none) michael@0: * michael@0: * @param aKey michael@0: * A string. michael@0: * @param aAllowError [optional] michael@0: * A boolean value. If set to true, an error response won't be treated michael@0: * as test failure. Default: false. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function getSettings(aKey, aAllowError) { michael@0: let request = michael@0: workingFrame.contentWindow.navigator.mozSettings.createLock().get(aKey); michael@0: return wrapDomRequestAsPromise(request) michael@0: .then(function resolve(aEvent) { michael@0: ok(true, "getSettings(" + aKey + ") - success"); michael@0: return aEvent.target.result[aKey]; michael@0: }, function reject(aEvent) { michael@0: ok(aAllowError, "getSettings(" + aKey + ") - error"); michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Set mozSettings values. michael@0: * michael@0: * Resolve if that mozSettings value is set successfully, reject otherwise. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: (none) michael@0: * michael@0: * @param aSettings michael@0: * An object of format |{key1: value1, key2: value2, ...}|. michael@0: * @param aAllowError [optional] michael@0: * A boolean value. If set to true, an error response won't be treated michael@0: * as test failure. Default: false. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setSettings(aSettings, aAllowError) { michael@0: let request = michael@0: workingFrame.contentWindow.navigator.mozSettings.createLock().set(aSettings); michael@0: return wrapDomRequestAsPromise(request) michael@0: .then(function resolve() { michael@0: ok(true, "setSettings(" + JSON.stringify(aSettings) + ")"); michael@0: }, function reject() { michael@0: ok(aAllowError, "setSettings(" + JSON.stringify(aSettings) + ")"); michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Set mozSettings value with only one key. michael@0: * michael@0: * Resolve if that mozSettings value is set successfully, reject otherwise. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: (none) michael@0: * michael@0: * @param aKey michael@0: * A string key. michael@0: * @param aValue michael@0: * An object value. michael@0: * @param aAllowError [optional] michael@0: * A boolean value. If set to true, an error response won't be treated michael@0: * as test failure. Default: false. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setSettings1(aKey, aValue, aAllowError) { michael@0: let settings = {}; michael@0: settings[aKey] = aValue; michael@0: return setSettings(settings, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings getter for SETTINGS_KEY_DATA_ENABLED. michael@0: */ michael@0: function getDataEnabled(aAllowError) { michael@0: return getSettings(SETTINGS_KEY_DATA_ENABLED, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings setter for SETTINGS_KEY_DATA_ENABLED. michael@0: */ michael@0: function setDataEnabled(aEnabled, aAllowError) { michael@0: return setSettings1(SETTINGS_KEY_DATA_ENABLED, aEnabled, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings getter for SETTINGS_KEY_DATA_ROAMING_ENABLED. michael@0: */ michael@0: function getDataRoamingEnabled(aAllowError) { michael@0: return getSettings(SETTINGS_KEY_DATA_ROAMING_ENABLED, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings setter for SETTINGS_KEY_DATA_ROAMING_ENABLED. michael@0: */ michael@0: function setDataRoamingEnabled(aEnabled, aAllowError) { michael@0: return setSettings1(SETTINGS_KEY_DATA_ROAMING_ENABLED, aEnabled, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings getter for SETTINGS_KEY_DATA_APN_SETTINGS. michael@0: */ michael@0: function getDataApnSettings(aAllowError) { michael@0: return getSettings(SETTINGS_KEY_DATA_APN_SETTINGS, aAllowError); michael@0: } michael@0: michael@0: /** michael@0: * Convenient MozSettings setter for SETTINGS_KEY_DATA_APN_SETTINGS. michael@0: */ michael@0: function setDataApnSettings(aApnSettings, aAllowError) { michael@0: return setSettings1(SETTINGS_KEY_DATA_APN_SETTINGS, aApnSettings, aAllowError); michael@0: } michael@0: michael@0: let mobileConnection; michael@0: michael@0: /** michael@0: * Push required permissions and test if michael@0: * |navigator.mozMobileConnections[]| exists. Resolve if it does, michael@0: * reject otherwise. michael@0: * michael@0: * Fulfill params: michael@0: * mobileConnection -- an reference to navigator.mozMobileMessage. michael@0: * michael@0: * Reject params: (none) michael@0: * michael@0: * @param aAdditonalPermissions [optional] michael@0: * An array of permission strings other than "mobileconnection" to be michael@0: * pushed. Default: empty string. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: 0. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function ensureMobileConnection(aAdditionalPermissions, aServiceId) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: aAdditionalPermissions = aAdditionalPermissions || []; michael@0: aServiceId = aServiceId || 0; michael@0: michael@0: if (aAdditionalPermissions.indexOf("mobileconnection") < 0) { michael@0: aAdditionalPermissions.push("mobileconnection"); michael@0: } michael@0: let permissions = []; michael@0: for (let perm of aAdditionalPermissions) { michael@0: permissions.push({ "type": perm, "allow": 1, "context": document }); michael@0: } michael@0: michael@0: SpecialPowers.pushPermissions(permissions, function() { michael@0: ok(true, "permissions pushed: " + JSON.stringify(permissions)); michael@0: michael@0: // Permission changes can't change existing Navigator.prototype michael@0: // objects, so grab our objects from a new Navigator. michael@0: workingFrame = document.createElement("iframe"); michael@0: workingFrame.addEventListener("load", function load() { michael@0: workingFrame.removeEventListener("load", load); michael@0: michael@0: mobileConnection = michael@0: workingFrame.contentWindow.navigator.mozMobileConnections[aServiceId]; michael@0: michael@0: if (mobileConnection) { michael@0: log("navigator.mozMobileConnections[" + aServiceId + "] is instance of " + michael@0: mobileConnection.constructor); michael@0: } else { michael@0: log("navigator.mozMobileConnections[" + aServiceId + "] is undefined"); michael@0: } michael@0: michael@0: if (mobileConnection instanceof MozMobileConnection) { michael@0: deferred.resolve(mobileConnection); michael@0: } else { michael@0: deferred.reject(); michael@0: } michael@0: }); michael@0: michael@0: document.body.appendChild(workingFrame); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: /** michael@0: * Wait for one named MobileConnection event. michael@0: * michael@0: * Resolve if that named event occurs. Never reject. michael@0: * michael@0: * Fulfill params: the DOMEvent passed. michael@0: * michael@0: * @param aEventName michael@0: * A string event name. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: the one indicated in michael@0: * start*TestCommon() or 0 if not indicated. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function waitForManagerEvent(aEventName, aServiceId) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: let mobileConn = mobileConnection; michael@0: if (aServiceId !== undefined) { michael@0: mobileConn = michael@0: workingFrame.contentWindow.navigator.mozMobileConnections[aServiceId]; michael@0: } michael@0: michael@0: mobileConn.addEventListener(aEventName, function onevent(aEvent) { michael@0: mobileConn.removeEventListener(aEventName, onevent); michael@0: michael@0: ok(true, "MobileConnection event '" + aEventName + "' got."); michael@0: deferred.resolve(aEvent); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: /** michael@0: * Get available networks. michael@0: * michael@0: * Fulfill params: michael@0: * An array of nsIDOMMozMobileNetworkInfo. michael@0: * Reject params: michael@0: * A DOMEvent. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function getNetworks() { michael@0: let request = mobileConnection.getNetworks(); michael@0: return wrapDomRequestAsPromise(request) michael@0: .then(() => request.result); michael@0: } michael@0: michael@0: /** michael@0: * Manually select a network. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: michael@0: * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' michael@0: * michael@0: * @param aNetwork michael@0: * A nsIDOMMozMobileNetworkInfo. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function selectNetwork(aNetwork) { michael@0: let request = mobileConnection.selectNetwork(aNetwork); michael@0: return wrapDomRequestAsPromise(request) michael@0: .then(null, () => { throw request.error }); michael@0: } michael@0: michael@0: /** michael@0: * Manually select a network and wait for a 'voicechange' event. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: michael@0: * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' michael@0: * michael@0: * @param aNetwork michael@0: * A nsIDOMMozMobileNetworkInfo. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function selectNetworkAndWait(aNetwork) { michael@0: let promises = []; michael@0: michael@0: promises.push(waitForManagerEvent("voicechange")); michael@0: promises.push(selectNetwork(aNetwork)); michael@0: michael@0: return Promise.all(promises); michael@0: } michael@0: michael@0: /** michael@0: * Automatically select a network. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: michael@0: * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function selectNetworkAutomatically() { michael@0: let request = mobileConnection.selectNetworkAutomatically(); michael@0: return wrapDomRequestAsPromise(request) michael@0: .then(null, () => { throw request.error }); michael@0: } michael@0: michael@0: /** michael@0: * Automatically select a network and wait for a 'voicechange' event. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: michael@0: * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function selectNetworkAutomaticallyAndWait() { michael@0: let promises = []; michael@0: michael@0: promises.push(waitForManagerEvent("voicechange")); michael@0: promises.push(selectNetworkAutomatically()); michael@0: michael@0: return Promise.all(promises); michael@0: } michael@0: michael@0: /** michael@0: * Set data connection enabling state and wait for "datachange" event. michael@0: * michael@0: * Resolve if data connection state changed to the expected one. Never reject. michael@0: * michael@0: * Fulfill params: (none) michael@0: * michael@0: * @param aEnabled michael@0: * A boolean state. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: the one indicated in michael@0: * start*TestCommon() or 0 if not indicated. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setDataEnabledAndWait(aEnabled, aServiceId) { michael@0: let deferred = Promise.defer(); michael@0: michael@0: let promises = []; michael@0: promises.push(waitForManagerEvent("datachange", aServiceId)); michael@0: promises.push(setDataEnabled(aEnabled)); michael@0: Promise.all(promises).then(function keepWaiting() { michael@0: let mobileConn = mobileConnection; michael@0: if (aServiceId !== undefined) { michael@0: mobileConn = michael@0: workingFrame.contentWindow.navigator.mozMobileConnections[aServiceId]; michael@0: } michael@0: // To ignore some transient states, we only resolve that deferred promise michael@0: // when the |connected| state equals to the expected one and never rejects. michael@0: let connected = mobileConn.data.connected; michael@0: if (connected == aEnabled) { michael@0: deferred.resolve(); michael@0: return; michael@0: } michael@0: michael@0: return waitForManagerEvent("datachange", aServiceId).then(keepWaiting); michael@0: }); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: /** michael@0: * Set voice/data state and wait for state change. michael@0: * michael@0: * Fulfill params: (none) michael@0: * michael@0: * @param aWhich michael@0: * "voice" or "data". michael@0: * @param aState michael@0: * "unregistered", "searching", "denied", "roaming", or "home". michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: the one indicated in michael@0: * start*TestCommon() or 0 if not indicated. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setEmulatorVoiceDataStateAndWait(aWhich, aState, aServiceId) { michael@0: let promises = []; michael@0: promises.push(waitForManagerEvent(aWhich + "change", aServiceId)); michael@0: michael@0: let cmd = "gsm " + aWhich + " " + aState; michael@0: promises.push(runEmulatorCmdSafe(cmd)); michael@0: return Promise.all(promises); michael@0: } michael@0: michael@0: /** michael@0: * Set voice and data roaming emulation and wait for state change. michael@0: * michael@0: * Fulfill params: (none) michael@0: * michael@0: * @param aRoaming michael@0: * A boolean state. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: the one indicated in michael@0: * start*TestCommon() or 0 if not indicated. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setEmulatorRoamingAndWait(aRoaming, aServiceId) { michael@0: function doSetAndWait(aWhich, aRoaming, aServiceId) { michael@0: let state = (aRoaming ? "roaming" : "home"); michael@0: return setEmulatorVoiceDataStateAndWait(aWhich, state, aServiceId) michael@0: .then(() => { michael@0: let mobileConn = mobileConnection; michael@0: if (aServiceId !== undefined) { michael@0: mobileConn = michael@0: workingFrame.contentWindow.navigator.mozMobileConnections[aServiceId]; michael@0: } michael@0: is(mobileConn[aWhich].roaming, aRoaming, michael@0: aWhich + ".roaming") michael@0: }); michael@0: } michael@0: michael@0: // Set voice registration state first and then data registration state. michael@0: return doSetAndWait("voice", aRoaming, aServiceId) michael@0: .then(() => doSetAndWait("data", aRoaming, aServiceId)); michael@0: } michael@0: michael@0: /** michael@0: * Get GSM location emulation. michael@0: * michael@0: * Fulfill params: michael@0: * { lac: , cid: } michael@0: * Reject params: michael@0: * result -- an array of emulator response lines. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function getEmulatorGsmLocation() { michael@0: let cmd = "gsm location"; michael@0: return runEmulatorCmdSafe(cmd) michael@0: .then(function(aResults) { michael@0: // lac: michael@0: // ci: michael@0: // OK michael@0: is(aResults[0].substring(0,3), "lac", "lac output"); michael@0: is(aResults[1].substring(0,2), "ci", "ci output"); michael@0: michael@0: let lac = parseInt(aResults[0].substring(5)); michael@0: lac = (lac < 0 ? 65535 : lac); michael@0: let cid = parseInt(aResults[1].substring(4)); michael@0: cid = (cid < 0 ? 268435455 : cid); michael@0: michael@0: return { lac: lac, cid: cid }; michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Set GSM location emulation. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: (none) michael@0: * michael@0: * @param aLac michael@0: * @param aCid michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setEmulatorGsmLocation(aLac, aCid) { michael@0: let cmd = "gsm location " + aLac + " " + aCid; michael@0: return runEmulatorCmdSafe(cmd); michael@0: } michael@0: michael@0: /** michael@0: * Get emulator operators info. michael@0: * michael@0: * Fulfill params: michael@0: * An array of { longName: , shortName: , mccMnc: }. michael@0: * Reject params: michael@0: * result -- an array of emulator response lines. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function getEmulatorOperatorNames() { michael@0: let cmd = "operator dumpall"; michael@0: return runEmulatorCmdSafe(cmd) michael@0: .then(function(aResults) { michael@0: let operators = []; michael@0: michael@0: for (let i = 0; i < aResults.length - 1; i++) { michael@0: let names = aResults[i].split(','); michael@0: operators.push({ michael@0: longName: names[0], michael@0: shortName: names[1], michael@0: mccMnc: names[2], michael@0: }); michael@0: } michael@0: michael@0: ok(true, "emulator operators list: " + JSON.stringify(operators)); michael@0: return operators; michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Set emulator operators info. michael@0: * michael@0: * Fulfill params: (none) michael@0: * Reject params: michael@0: * result -- an array of emulator response lines. michael@0: * michael@0: * @param aOperator michael@0: * "home" or "roaming". michael@0: * @param aLongName michael@0: * A string. michael@0: * @param aShortName michael@0: * A string. michael@0: * @param aMcc [optional] michael@0: * A string. michael@0: * @param aMnc [optional] michael@0: * A string. michael@0: * michael@0: * @return A deferred promise. michael@0: */ michael@0: function setEmulatorOperatorNames(aOperator, aLongName, aShortName, aMcc, aMnc) { michael@0: const EMULATOR_OPERATORS = [ "home", "roaming" ]; michael@0: michael@0: let index = EMULATOR_OPERATORS.indexOf(aOperator); michael@0: if (index < 0) { michael@0: throw "invalid operator"; michael@0: } michael@0: michael@0: let cmd = "operator set " + index + " " + aLongName + "," + aShortName; michael@0: if (aMcc && aMnc) { michael@0: cmd = cmd + "," + aMcc + aMnc; michael@0: } michael@0: return runEmulatorCmdSafe(cmd) michael@0: .then(function(aResults) { michael@0: let exp = "^" + aLongName + "," + aShortName + ","; michael@0: if (aMcc && aMnc) { michael@0: cmd = cmd + aMcc + aMnc; michael@0: } michael@0: michael@0: let re = new RegExp(exp); michael@0: ok(aResults[index].match(new RegExp(exp)), michael@0: "Long/short name and/or mcc/mnc should be changed."); michael@0: }); michael@0: } michael@0: michael@0: let _networkManager; michael@0: michael@0: /** michael@0: * Get internal NetworkManager service. michael@0: */ michael@0: function getNetworkManager() { michael@0: if (!_networkManager) { michael@0: _networkManager = Cc["@mozilla.org/network/manager;1"] michael@0: .getService(Ci.nsINetworkManager); michael@0: ok(_networkManager, "NetworkManager"); michael@0: } michael@0: michael@0: return _networkManager; michael@0: } michael@0: michael@0: let _numOfRadioInterfaces; michael@0: michael@0: /* michael@0: * Get number of radio interfaces. Default is 1 if preference is not set. michael@0: */ michael@0: function getNumOfRadioInterfaces() { michael@0: if (!_numOfRadioInterfaces) { michael@0: try { michael@0: _numOfRadioInterfaces = SpecialPowers.getIntPref("ril.numRadioInterfaces"); michael@0: } catch (ex) { michael@0: _numOfRadioInterfaces = 1; // Pref not set. michael@0: } michael@0: } michael@0: michael@0: return _numOfRadioInterfaces; michael@0: } michael@0: michael@0: /** michael@0: * Flush permission settings and call |finish()|. michael@0: */ michael@0: function cleanUp() { michael@0: waitFor(function() { michael@0: SpecialPowers.flushPermissions(function() { michael@0: // Use ok here so that we have at least one test run. michael@0: ok(true, "permissions flushed"); michael@0: michael@0: finish(); michael@0: }); michael@0: }, function() { michael@0: return _pendingEmulatorCmdCount === 0; michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Basic test routine helper for mobile connection tests. michael@0: * michael@0: * This helper does nothing but clean-ups. michael@0: * michael@0: * @param aTestCaseMain michael@0: * A function that takes no parameter. michael@0: */ michael@0: function startTestBase(aTestCaseMain) { michael@0: Promise.resolve() michael@0: .then(aTestCaseMain) michael@0: .then(cleanUp, function() { michael@0: ok(false, 'promise rejects during test.'); michael@0: cleanUp(); michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Common test routine helper for mobile connection tests. michael@0: * michael@0: * This function ensures global |mobileConnection| variable is available during michael@0: * the process and performs clean-ups as well. michael@0: * michael@0: * @param aTestCaseMain michael@0: * A function that takes one parameter -- mobileConnection. michael@0: * @param aAdditonalPermissions [optional] michael@0: * An array of permission strings other than "mobileconnection" to be michael@0: * pushed. Default: empty string. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: 0. michael@0: */ michael@0: function startTestCommon(aTestCaseMain, aAdditionalPermissions, aServiceId) { michael@0: startTestBase(function() { michael@0: return ensureMobileConnection(aAdditionalPermissions, aServiceId) michael@0: .then(aTestCaseMain); michael@0: }); michael@0: } michael@0: michael@0: /** michael@0: * Common test routine helper for multi-sim mobile connection tests. The test michael@0: * ends immediately if the device tested is not multi-sim. michael@0: * michael@0: * This function ensures global |mobileConnection| variable is available during michael@0: * the process and performs clean-ups as well. michael@0: * michael@0: * @param aTestCaseMain michael@0: * A function that takes one parameter -- mobileConnection. michael@0: * @param aAdditonalPermissions [optional] michael@0: * An array of permission strings other than "mobileconnection" to be michael@0: * pushed. Default: empty string. michael@0: * @param aServiceId [optional] michael@0: * A numeric DSDS service id. Default: 0. michael@0: */ michael@0: function startDSDSTestCommon(aTestCaseMain, aAdditionalPermissions, aServiceId) { michael@0: if (getNumOfRadioInterfaces() > 1) { michael@0: startTestBase(function() { michael@0: return ensureMobileConnection(aAdditionalPermissions, aServiceId) michael@0: .then(aTestCaseMain); michael@0: }); michael@0: } else { michael@0: log("Skipping DSDS tests on single SIM device.") michael@0: ok(true); // We should run at least one test. michael@0: cleanUp(); michael@0: } michael@0: }