gecko-dev/dom/camera/test/test_camera_auto_focus.html
Andrew Osmond 5a7c3f4749 Bug 1144211 - Improve code coverage of camera mochitests. r=mikeh
--HG--
rename : dom/camera/test/test_camera_hardware_auto_focus_moving_cb.html => dom/camera/test/test_camera_auto_focus.html
rename : dom/camera/test/test_camera_bad_initial_config.html => dom/camera/test/test_camera_configuration.html
rename : dom/camera/test/test_camera_hardware_face_detection.html => dom/camera/test/test_camera_face_detection.html
rename : dom/camera/test/test_bug975472.html => dom/camera/test/test_camera_release.html
rename : dom/camera/test/test_camera_hardware_failures.html => dom/camera/test/test_camera_take_picture.html
extra : amend_source : edb877b83a258230767eca02fa3d0500ab865a0e
2015-03-17 13:01:24 -04:00

239 lines
8.1 KiB
HTML

<!DOCTYPE HTML>
<html>
<head>
<title>Test for auto focus</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var suite = new CameraTestSuite();
/* Each discrete test case can be added to the test queue here.
They won't be run until you call suite setup and run. */
suite.test('auto-focus-failures', function() {
function startAutoFocusFail(p) {
suite.hw.attach({
autoFocus: function() {
suite.hw.fireAutoFocusComplete(false);
}
});
return suite.camera.autoFocus();
}
function resolveAutoFocusFail(focused) {
ok(!focused, 'autoFocus() should be unfocused: ' + focused);
}
function startAutoFocusError(p) {
suite.hw.attach({
autoFocus: function() {
throw SpecialPowers.Cr.NS_ERROR_FAILURE;
}
});
return suite.camera.autoFocus();
}
function rejectAutoFocusError(e) {
ok(e.name === 'NS_ERROR_FAILURE', 'autoFocus() should fail: ' + e);
}
/* This is the promise chain which drives the test execution.
suite.getCamera
This returns a promise which is resolved when the suite
acquires the camera object (i.e. returns as if one
called cameraManager.getCamera() directly). It saves
the CameraControl reference in suite.camera and will
automatically release it for you when the test is
completed.
.then(startAutoFocusFail, suite.rejectGetCamera)
If the getCamera promise is resolved, startAutoFocusFail
will be called. That function attaches a handler to
the camera test hardware to intercept the auto focus
driver call so that we can change the behaviour to
trigger an OnAutoFocusComplete(false) event. It then
calls camera.autoFocus() and returns the promise for
that camera call so that the next promise in the chain
can block waiting for that promise to be fulfilled.
If the getCamera promise is rejected,
suite.rejectGetCamera will be called. This is a helper
handler provided by the test suite; it will log
a get camera failure and fail the test via ok, and
return a new promise rejecting *without* an error
object (i.e. promise parameter is undefined). This is
important because all reject handlers further down
the promise chain will still be called due to the
failure. However since we replaced the promise with
an error object, with a promise without one, we can
use this to identify errors that have already been
handled.
.then(resolveAutoFocusFail, suite.rejectAutoFocus)
If the suite.camera.autoFocus() promise is resolved,
resolveAutoFocusFail will be called. That function
simply verifies the result from the autoFocus() call.
It should be false, given the modified behaviour we
gave the driver. Since it doesn't return a new promise
explicitly, it will generate a new promise which is
already resolved (without the focused state parameter,
will now be undefined to the next .then handler).
If the suite.camera.autoFocus() promise is rejected,
we want to fail the test case again, just like when
suite.getCamera() failed.
.then(startAutoFocusError)
Assuming the first suite.camera.autoFocus() promise
was resolved, startAutoFocusError will be called.
That function is similar to startAutoFocusFail but
now it throws an error in the intercepted auto focus
driver call in order to trigger an OnUserError(kAutoFocus)
event. It then calls and returns the promise from
suite.camera.autoFocus().
.then(suite.expectedRejectAutoFocus, rejectAutoFocusError)
Now we are expecting the previous suite.camera.autoFocus()
promise to be rejected, which would call
rejectAutoFocusError. This simply verifies that we
got the error we expected.
If, on the other hand, it somehow succeeded, we
let suite.expectedRejectAutoFocus handle it, which
similar to the suite.rejectAutoFocus method, will
fail and return an empty rejected promise.
Note that this method itself returns the promise chain.
This allows the test suite to 1) capture any unhandled
errors in the promise chain and ensure the test case
fails as a result, and 2) perform any cleanup operations
such as resetting low memory state, releasing the camera,
etc, before starting the next test.
*/
return suite.getCamera()
.then(startAutoFocusFail, suite.rejectGetCamera)
.then(resolveAutoFocusFail, suite.rejectAutoFocus)
.then(startAutoFocusError)
.then(suite.expectedRejectAutoFocus, rejectAutoFocusError)
});
suite.test('auto-focus-moving', function() {
function triggerAutoFocusMoving(p) {
var sync = new Promise(function(resolve, reject) {
function onEvent(e) {
suite.camera.removeEventListener('focus', onEvent);
ok(e.newState === 'focusing', 'autofocus event state focusing == ' + e.newState);
resolve();
}
suite.camera.addEventListener('focus', onEvent);
});
suite.hw.fireAutoFocusMoving(true);
return sync;
}
function waitAutoFocusComplete(p) {
var sync = new Promise(function(resolve, reject) {
function onEvent(e) {
suite.camera.removeEventListener('focus', onEvent);
ok(e.newState === 'focused', 'autofocus event state focused == ' + e.newState);
resolve();
}
suite.camera.addEventListener('focus', onEvent);
});
// Missing the fireAutoFocusComplete but it should timeout on its own
suite.hw.fireAutoFocusMoving(false);
return sync;
}
function runAutoFocusCycle(p) {
return triggerAutoFocusMoving(p)
.then(waitAutoFocusComplete);
}
/* If the driver doesn't supply an onAutoFocusComplete notification,
gecko will timeout and provide it. After three times, it will no
longer rely upon a timeout and fire it immediately. */
return suite.getCamera()
.then(runAutoFocusCycle)
.then(runAutoFocusCycle)
.then(runAutoFocusCycle)
.then(runAutoFocusCycle);
});
suite.test('auto-focus-interrupted', function() {
// bug 1022766
function triggerAutoFocus(p) {
return new Promise(function(resolve, reject) {
var firstCall = false;
var secondCall = false;
function end() {
if (firstCall && secondCall) {
resolve();
}
}
// It doesn't matter if the emulator supports focus or not;
// this is just testing the sequencing.
suite.camera.autoFocus().then(function(p) {
ok(false, "First call to autoFocus() succeeded unexpectedly");
firstCall = true;
end();
}, function(e) {
ok(e.name === 'NS_ERROR_IN_PROGRESS', 'First call to autoFocus() failed with: ' + e);
firstCall = true;
end();
});
suite.camera.autoFocus().then(function(p) {
ok(true, "Second call to autoFocus() succeeded");
secondCall = true;
end();
}, function(e) {
ok(false, "Second call to autoFocus() failed unexpectedly with: " + e);
secondCall = true;
end();
});
});
}
return suite.getCamera()
.then(triggerAutoFocus, suite.rejectGetCamera)
});
suite.test('cancel-auto-focus', function() {
function cancelAutoFocus(p) {
var promise = new Promise(function(resolve, reject) {
suite.hw.attach({
cancelAutoFocus: function() {
ok(true, 'got cancel auto focus');
resolve();
}
});
});
suite.camera.resumeContinuousFocus();
return promise;
}
return suite.getCamera()
.then(cancelAutoFocus, suite.rejectGetCamera);
});
suite.setup()
.then(suite.run);
</script>
</body>
</html>