michael@0: var CameraTest = (function() { michael@0: 'use strict'; michael@0: michael@0: /** michael@0: * 'camera.control.test.enabled' is queried in Gecko to enable different michael@0: * test modes in the camera stack. The only currently-supported setting michael@0: * is 'hardware', which wraps the Gonk camera abstraction class in a michael@0: * shim class that supports injecting hardware camera API failures into michael@0: * the execution path. michael@0: * michael@0: * The affected API is specified by the 'camera.control.test.hardware' michael@0: * pref. Currently supported values should be determined by inspecting michael@0: * TestGonkCameraHardware.cpp. michael@0: * michael@0: * Some API calls are simple: e.g. 'start-recording-failure' will cause michael@0: * the DOM-facing startRecording() call to fail. More complex tests like michael@0: * 'take-picture-failure' will cause the takePicture() API to fail, while michael@0: * 'take-picture-process-failure' will simulate a failure of the michael@0: * asynchronous picture-taking process, even if the initial API call michael@0: * path seems to have succeeded. michael@0: * michael@0: * If 'camera.control.test.hardware.gonk.parameters' is set, it will cause michael@0: * the contents of that string to be appended to the string of parameters michael@0: * pulled from the Gonk camera library. This allows tests to inject fake michael@0: * settings/capabilities for features not supported by the emulator. These michael@0: * parameters are one or more semicolon-delimited key=value pairs, e.g. to michael@0: * pretend the emulator supports zoom: michael@0: * michael@0: * zoom-ratios=100,150,200,300,400;max-zoom=4 michael@0: * michael@0: * This means (of course) that neither the key not the value tokens can michael@0: * contain either equals signs or semicolons. The test shim doesn't enforce michael@0: * this so that we can test getting junk from the camera library as well. michael@0: */ michael@0: const PREF_TEST_ENABLED = "camera.control.test.enabled"; michael@0: const PREF_TEST_HARDWARE = "camera.control.test.hardware"; michael@0: const PREF_TEST_EXTRA_PARAMETERS = "camera.control.test.hardware.gonk.parameters"; michael@0: var oldTestEnabled; michael@0: var oldTestHw; michael@0: var testMode; michael@0: michael@0: function testHardwareSetFakeParameters(parameters, callback) { michael@0: SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_EXTRA_PARAMETERS, parameters]]}, function() { michael@0: var setParams = SpecialPowers.getCharPref(PREF_TEST_EXTRA_PARAMETERS); michael@0: ise(setParams, parameters, "Extra test parameters '" + setParams + "'"); michael@0: if (callback) { michael@0: callback(setParams); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testHardwareClearFakeParameters(callback) { michael@0: SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_EXTRA_PARAMETERS]]}, callback); michael@0: } michael@0: michael@0: function testHardwareSet(test, callback) { michael@0: SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, test]]}, function() { michael@0: var setTest = SpecialPowers.getCharPref(PREF_TEST_HARDWARE); michael@0: ise(setTest, test, "Test subtype set to " + setTest); michael@0: if (callback) { michael@0: callback(setTest); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testHardwareDone(callback) { michael@0: testMode = null; michael@0: if (oldTestHw) { michael@0: SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_HARDWARE, oldTestHw]]}, callback); michael@0: } else { michael@0: SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_HARDWARE]]}, callback); michael@0: } michael@0: } michael@0: michael@0: function testBegin(mode, callback) { michael@0: SimpleTest.waitForExplicitFinish(); michael@0: try { michael@0: oldTestEnabled = SpecialPowers.getCharPref(PREF_TEST_ENABLED); michael@0: } catch(e) { } michael@0: SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, mode]]}, function() { michael@0: var setMode = SpecialPowers.getCharPref(PREF_TEST_ENABLED); michael@0: ise(setMode, mode, "Test mode set to " + setMode); michael@0: if (setMode === "hardware") { michael@0: try { michael@0: oldTestHw = SpecialPowers.getCharPref(PREF_TEST_HARDWARE); michael@0: } catch(e) { } michael@0: testMode = { michael@0: set: testHardwareSet, michael@0: setFakeParameters: testHardwareSetFakeParameters, michael@0: clearFakeParameters: testHardwareClearFakeParameters, michael@0: done: testHardwareDone michael@0: }; michael@0: if (callback) { michael@0: callback(testMode); michael@0: } michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testEnd(callback) { michael@0: // A chain of clean-up functions.... michael@0: function allCleanedUp() { michael@0: SimpleTest.finish(); michael@0: if (callback) { michael@0: callback(); michael@0: } michael@0: } michael@0: function cleanUpTestEnabled() { michael@0: var next = allCleanedUp; michael@0: if (oldTestEnabled) { michael@0: SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, oldTestEnabled]]}, next); michael@0: } else { michael@0: SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_ENABLED]]}, next); michael@0: } michael@0: } michael@0: function cleanUpTest() { michael@0: var next = cleanUpTestEnabled; michael@0: if (testMode) { michael@0: testMode.done(next); michael@0: testMode = null; michael@0: } else { michael@0: next(); michael@0: } michael@0: } michael@0: function cleanUpExtraParameters() { michael@0: var next = cleanUpTest; michael@0: if (testMode) { michael@0: testMode.clearFakeParameters(next); michael@0: } else { michael@0: next(); michael@0: } michael@0: } michael@0: michael@0: cleanUpExtraParameters(); michael@0: } michael@0: michael@0: ise(SpecialPowers.sanityCheck(), "foo", "SpecialPowers passed sanity check"); michael@0: return { michael@0: begin: testBegin, michael@0: end: testEnd michael@0: }; michael@0: michael@0: })();