1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/camera/test/test_camera_hardware_face_detection.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,320 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=965420 1.8 +--> 1.9 +<head> 1.10 + <title>Bug 965420 - Test camera hardware API for face detection</title> 1.11 + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> 1.12 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.13 + <script type="text/javascript" src="camera_common.js"></script> 1.14 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.15 +</head> 1.16 +<body> 1.17 + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965420">Mozilla Bug 965420</a> 1.18 + <video id="viewfinder" width = "200" height = "200" autoplay></video> 1.19 + <img src="#" alt="This image is going to load" id="testimage"/> 1.20 + 1.21 +<script class="testbody" type="text/javascript;version=1.7"> 1.22 + 1.23 +var whichCamera = navigator.mozCameras.getListOfCameras()[0]; 1.24 +var initialConfig = { 1.25 + mode: 'picture', 1.26 + recorderProfile: 'cif', 1.27 + previewSize: { 1.28 + width: 352, 1.29 + height: 288 1.30 + } 1.31 +}; 1.32 + 1.33 +const PREF_FACEDETECTION_ENABLED = "camera.control.face_detection.enabled"; 1.34 + 1.35 +var cameraObj; 1.36 +var oldPref; 1.37 + 1.38 +// Shorthand functions 1.39 +function end() { 1.40 + function reallyEnd() { 1.41 + CameraTest.end(); 1.42 + } 1.43 + if (oldPref) { 1.44 + SpecialPowers.pushPrefEnv( 1.45 + {'set': [[PREF_FACEDETECTION_ENABLED, oldPref]]}, reallyEnd); 1.46 + } else { 1.47 + SpecialPowers.pushPrefEnv( 1.48 + {'clear': [[PREF_FACEDETECTION_ENABLED]]}, reallyEnd); 1.49 + } 1.50 +} 1.51 +function next() { 1.52 + CameraTest.next(); 1.53 +} 1.54 + 1.55 +function compareFaces(aFaces, expected) 1.56 +{ 1.57 + ok(aFaces, "have detected faces object"); 1.58 + ok(aFaces.length == expected.faces.length, 1.59 + "expected=" + expected.faces.length + ", got=" + aFaces.length); 1.60 + aFaces.forEach(function (face, index) { 1.61 + let result = compareFace(face, expected.faces[index]); 1.62 + ok(result === "ok", "face check: " + result); 1.63 + if (result !== "ok") { 1.64 + return false; 1.65 + } 1.66 + }); 1.67 + return true; 1.68 +} 1.69 + 1.70 +function compareFace(aFace, expected) 1.71 +{ 1.72 + if (aFace.id != expected.id) { 1.73 + return "expected face.id=" + expected.id + ", got=" + aFace.id; 1.74 + } 1.75 + if (aFace.score != expected.score) { 1.76 + return "expected face.score=" + expected.score + ", got=" + aFace.score; 1.77 + } 1.78 + if (!aFace.bounds) { 1.79 + return "face.bounds is missing"; 1.80 + } 1.81 + if (aFace.bounds.left != expected.bounds.left || 1.82 + aFace.bounds.top != expected.bounds.top || 1.83 + aFace.bounds.right != expected.bounds.right || 1.84 + aFace.bounds.bottom != expected.bounds.bottom) { 1.85 + return "expected face.bounds=" + expected.bounds.toSource() + 1.86 + ", got=({left:" + aFace.bounds.left + ", top:" + aFace.bounds.top + ", right:" + aFace.bounds.right + ", bottom:" + aFace.bounds.bottom + "})"; 1.87 + } 1.88 + 1.89 + if (aFace.leftEye && !expected.leftEye) { 1.90 + return "expected null face.leftEye, got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})"; 1.91 + } 1.92 + if (!aFace.leftEye && expected.leftEye) { 1.93 + return "expected face.leftEye=" + expected.leftEye.toSource() + ", got null leftEye"; 1.94 + } 1.95 + if (aFace.leftEye && expected.leftEye && 1.96 + (aFace.leftEye.x != expected.leftEye.x || aFace.leftEye.y != expected.leftEye.y)) { 1.97 + return "expected face.leftEye=" + expected.leftEye.toSource() + 1.98 + ", got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})"; 1.99 + } 1.100 + 1.101 + if (aFace.rightEye && !expected.rightEye) { 1.102 + return "expected null face.rightEye, got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})"; 1.103 + } 1.104 + if (!aFace.rightEye && expected.rightEye) { 1.105 + return "expected face.rightEye=" + expected.rightEye.toSource() + ", got null rightEye"; 1.106 + } 1.107 + if (aFace.rightEye && expected.rightEye && 1.108 + (aFace.rightEye.x != expected.rightEye.x || aFace.rightEye.y != expected.rightEye.y)) { 1.109 + return "expected face.rightEye=" + expected.rightEye.toSource() + 1.110 + ", got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})"; 1.111 + } 1.112 + 1.113 + if (aFace.mouth && !expected.mouth) { 1.114 + return "expected null face.mouth, got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})"; 1.115 + } 1.116 + if (!aFace.mouth && expected.mouth) { 1.117 + return "expected face.mouth=" + expected.mouth.toSource() + ", got null mouth"; 1.118 + } 1.119 + if (aFace.mouth && expected.mouth && 1.120 + (aFace.mouth.x != expected.mouth.x || aFace.mouth.y != expected.mouth.y)) { 1.121 + return "expected face.mouth=" + expected.mouth.toSource() + 1.122 + ", got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})"; 1.123 + } 1.124 + 1.125 + return "ok"; 1.126 +} 1.127 + 1.128 +var tests = [ 1.129 + { 1.130 + key: "face-detection-detected-one-face", 1.131 + func: function testFaceDetectionFoundOneFace(camera) { 1.132 + var expected = { 1.133 + faces: [ { 1.134 + id: 1, 1.135 + score: 2, 1.136 + bounds: { 1.137 + left: 3, 1.138 + top: 4, 1.139 + right: 5, 1.140 + bottom: 6 1.141 + }, 1.142 + leftEye: { 1.143 + x: 7, 1.144 + y: 8 1.145 + }, 1.146 + rightEye: { 1.147 + x: 9, 1.148 + y: 10 1.149 + }, 1.150 + mouth: { 1.151 + x: 11, 1.152 + y: 12 1.153 + } 1.154 + } ] 1.155 + }; 1.156 + camera.onFacesDetected = function(aFaces) { 1.157 + ok(compareFaces(aFaces, expected), 1.158 + "onFaceDetected received the detected faces correctly"); 1.159 + camera.stopFaceDetection(); 1.160 + next(); 1.161 + } 1.162 + camera.startFaceDetection(); 1.163 + } 1.164 + }, 1.165 + { 1.166 + key: "face-detection-detected-two-faces", 1.167 + func: function testFaceDetectionFoundTwoFace(camera) { 1.168 + var expected = { 1.169 + faces: [ { 1.170 + id: 1, 1.171 + score: 2, 1.172 + bounds: { 1.173 + left: 3, 1.174 + top: 4, 1.175 + right: 5, 1.176 + bottom: 6 1.177 + }, 1.178 + leftEye: { 1.179 + x: 7, 1.180 + y: 8 1.181 + }, 1.182 + rightEye: { 1.183 + x: 9, 1.184 + y: 10 1.185 + }, 1.186 + mouth: { 1.187 + x: 11, 1.188 + y: 12 1.189 + } 1.190 + }, 1.191 + { 1.192 + id: 13, 1.193 + score: 14, 1.194 + bounds: { 1.195 + left: 15, 1.196 + top: 16, 1.197 + right: 17, 1.198 + bottom: 18 1.199 + }, 1.200 + leftEye: { 1.201 + x: 19, 1.202 + y: 20 1.203 + }, 1.204 + rightEye: { 1.205 + x: 21, 1.206 + y: 22 1.207 + }, 1.208 + mouth: { 1.209 + x: 23, 1.210 + y: 24 1.211 + } 1.212 + } ] 1.213 + }; 1.214 + camera.onFacesDetected = function(aFaces) { 1.215 + ok(compareFaces(aFaces, expected), 1.216 + "onFaceDetected received the detected faces correctly"); 1.217 + camera.stopFaceDetection(); 1.218 + next(); 1.219 + } 1.220 + camera.startFaceDetection(); 1.221 + } 1.222 + }, 1.223 + { 1.224 + key: "face-detection-detected-one-face-no-features", 1.225 + func: function (camera) { 1.226 + var expected = { 1.227 + faces: [ { 1.228 + id: 1, 1.229 + score: 100, 1.230 + bounds: { 1.231 + left: 3, 1.232 + top: 4, 1.233 + right: 5, 1.234 + bottom: 6 1.235 + }, 1.236 + leftEye: null, 1.237 + rightEye: null, 1.238 + mouth: null 1.239 + } ] 1.240 + }; 1.241 + camera.onFacesDetected = function(aFaces) { 1.242 + ok(compareFaces(aFaces, expected), 1.243 + "onFaceDetected received the detected faces correctly"); 1.244 + camera.stopFaceDetection(); 1.245 + next(); 1.246 + } 1.247 + camera.startFaceDetection(); 1.248 + } 1.249 + }, 1.250 + { 1.251 + key: "face-detection-no-faces-detected", 1.252 + func: function (camera) { 1.253 + var expected = { 1.254 + faces: [] 1.255 + }; 1.256 + camera.onFacesDetected = function(aFaces) { 1.257 + ok(compareFaces(aFaces, expected), 1.258 + "onFaceDetected received the detected faces correctly"); 1.259 + camera.stopFaceDetection(); 1.260 + next(); 1.261 + } 1.262 + camera.startFaceDetection(); 1.263 + } 1.264 + }, 1.265 +]; 1.266 + 1.267 +var testGenerator = function() { 1.268 + for (var i = 0; i < tests.length; ++i ) { 1.269 + yield tests[i]; 1.270 + } 1.271 +}(); 1.272 + 1.273 +window.addEventListener('beforeunload', function() { 1.274 + document.getElementById('viewfinder').mozSrcObject = null; 1.275 + if (cameraObj) { 1.276 + cameraObj.release(); 1.277 + cameraObj = null; 1.278 + } 1.279 +}); 1.280 + 1.281 +// Must call CameraTest.begin() before any other async methods. 1.282 +CameraTest.begin("hardware", function(test) { 1.283 + // If the pref doesn't exist, this get will fail; catch it and continue. 1.284 + try { 1.285 + oldPref = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED); 1.286 + } catch(e) { } 1.287 + 1.288 + SpecialPowers.pushPrefEnv({'set': [[PREF_FACEDETECTION_ENABLED, true]]}, function() { 1.289 + var enabled; 1.290 + try { 1.291 + enabled = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED); 1.292 + } catch(e) { } 1.293 + ok(enabled, PREF_FACEDETECTION_ENABLED + " is " + enabled); 1.294 + 1.295 + function onSuccess(camera, config) { 1.296 + document.getElementById('viewfinder').mozSrcObject = camera; 1.297 + cameraObj = camera; 1.298 + CameraTest.next = function() { 1.299 + try { 1.300 + var t = testGenerator.next(); 1.301 + test.set(t.key, t.func.bind(undefined, camera)); 1.302 + } catch(e) { 1.303 + if (e instanceof StopIteration) { 1.304 + end(); 1.305 + } else { 1.306 + throw e; 1.307 + } 1.308 + } 1.309 + }; 1.310 + next(); 1.311 + } 1.312 + function onError(error) { 1.313 + ok(false, "getCamera() failed with: " + error); 1.314 + end(); 1.315 + } 1.316 + navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError); 1.317 + }) 1.318 +}); 1.319 + 1.320 +</script> 1.321 +</body> 1.322 + 1.323 +</html>