Bumping manifests a=b2g-bump
[gecko.git] / dom / camera / TestGonkCameraHardware.cpp
blob418388e2247ea4fce9987161582f08442c904862
1 /*
2 * Copyright (C) 2013-2014 Mozilla Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "TestGonkCameraHardware.h"
19 #include "CameraPreferences.h"
20 #include "nsThreadUtils.h"
22 using namespace android;
23 using namespace mozilla;
25 TestGonkCameraHardware::TestGonkCameraHardware(nsGonkCameraControl* aTarget,
26 uint32_t aCameraId,
27 const sp<Camera>& aCamera)
28 : GonkCameraHardware(aTarget, aCameraId, aCamera)
30 DOM_CAMERA_LOGA("v===== Created TestGonkCameraHardware =====v\n");
31 DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n",
32 __func__, __LINE__, this, aTarget);
33 MOZ_COUNT_CTOR(TestGonkCameraHardware);
36 TestGonkCameraHardware::~TestGonkCameraHardware()
38 MOZ_COUNT_DTOR(TestGonkCameraHardware);
39 DOM_CAMERA_LOGA("^===== Destroyed TestGonkCameraHardware =====^\n");
42 nsresult
43 TestGonkCameraHardware::Init()
45 if (IsTestCase("init-failure")) {
46 return NS_ERROR_NOT_INITIALIZED;
49 return GonkCameraHardware::Init();
52 const nsCString
53 TestGonkCameraHardware::TestCase()
55 nsCString test;
56 CameraPreferences::GetPref("camera.control.test.hardware", test);
57 return test;
60 const nsCString
61 TestGonkCameraHardware::GetExtraParameters()
63 /**
64 * The contents of this pref are appended to the flattened string of
65 * parameters stuffed into GonkCameraParameters by the camera library.
66 * It consists of semicolon-delimited key=value pairs, e.g.
68 * focus-mode=auto;flash-mode=auto;preview-size=1024x768
70 * The unflattening process breaks this string up on semicolon boundaries
71 * and sets an entry in a hashtable of strings with the token before
72 * the equals sign as the key, and the token after as the value. Because
73 * the string is parsed in order, key=value pairs occuring later in the
74 * string will replace value pairs appearing earlier, making it easy to
75 * inject fake, testable values into the parameters table.
77 * One constraint of this approach is that neither the key nor the value
78 * may contain equals signs or semicolons. We don't enforce that here
79 * so that we can also test correct handling of improperly-formatted values.
81 nsCString parameters;
82 CameraPreferences::GetPref("camera.control.test.hardware.gonk.parameters", parameters);
83 DOM_CAMERA_LOGA("TestGonkCameraHardware : extra-parameters '%s'\n",
84 parameters.get());
85 return parameters;
88 bool
89 TestGonkCameraHardware::IsTestCaseInternal(const char* aTest, const char* aFile, int aLine)
91 if (TestCase().EqualsASCII(aTest)) {
92 DOM_CAMERA_LOGA("TestGonkCameraHardware : test-case '%s' (%s:%d)\n",
93 aTest, aFile, aLine);
94 return true;
97 return false;
101 TestGonkCameraHardware::TestCaseError(int aDefaultError)
103 // for now, just return the default error
104 return aDefaultError;
108 TestGonkCameraHardware::AutoFocus()
110 class AutoFocusFailure : public nsRunnable
112 public:
113 AutoFocusFailure(nsGonkCameraControl* aTarget)
114 : mTarget(aTarget)
117 NS_IMETHODIMP
118 Run()
120 OnAutoFocusComplete(mTarget, false);
121 return NS_OK;
124 protected:
125 nsGonkCameraControl* mTarget;
128 if (IsTestCase("auto-focus-failure")) {
129 return TestCaseError(UNKNOWN_ERROR);
131 if (IsTestCase("auto-focus-process-failure")) {
132 nsresult rv = NS_DispatchToCurrentThread(new AutoFocusFailure(mTarget));
133 if (NS_SUCCEEDED(rv)) {
134 return OK;
136 DOM_CAMERA_LOGE("Failed to dispatch AutoFocusFailure runnable (0x%08x)\n", rv);
137 return UNKNOWN_ERROR;
140 return GonkCameraHardware::AutoFocus();
143 // These classes have to be external to StartFaceDetection(), at least
144 // until we pick up gcc 4.5, which supports local classes as template
145 // arguments.
146 class FaceDetected : public nsRunnable
148 public:
149 FaceDetected(nsGonkCameraControl* aTarget)
150 : mTarget(aTarget)
153 ~FaceDetected()
155 ReleaseFacesArray();
158 NS_IMETHODIMP
159 Run()
161 InitMetaData();
162 OnFacesDetected(mTarget, &mMetaData);
163 return NS_OK;
166 protected:
167 virtual nsresult InitMetaData() = 0;
169 nsresult
170 AllocateFacesArray(uint32_t num)
172 mMetaData.faces = new camera_face_t[num];
173 return NS_OK;
176 nsresult
177 ReleaseFacesArray()
179 delete [] mMetaData.faces;
180 mMetaData.faces = nullptr;
181 return NS_OK;
184 nsRefPtr<nsGonkCameraControl> mTarget;
185 camera_frame_metadata_t mMetaData;
188 class OneFaceDetected : public FaceDetected
190 public:
191 OneFaceDetected(nsGonkCameraControl* aTarget)
192 : FaceDetected(aTarget)
195 nsresult
196 InitMetaData() MOZ_OVERRIDE
198 mMetaData.number_of_faces = 1;
199 AllocateFacesArray(1);
200 mMetaData.faces[0].id = 1;
201 mMetaData.faces[0].score = 2;
202 mMetaData.faces[0].rect[0] = 3;
203 mMetaData.faces[0].rect[1] = 4;
204 mMetaData.faces[0].rect[2] = 5;
205 mMetaData.faces[0].rect[3] = 6;
206 mMetaData.faces[0].left_eye[0] = 7;
207 mMetaData.faces[0].left_eye[1] = 8;
208 mMetaData.faces[0].right_eye[0] = 9;
209 mMetaData.faces[0].right_eye[1] = 10;
210 mMetaData.faces[0].mouth[0] = 11;
211 mMetaData.faces[0].mouth[1] = 12;
213 return NS_OK;
217 class TwoFacesDetected : public FaceDetected
219 public:
220 TwoFacesDetected(nsGonkCameraControl* aTarget)
221 : FaceDetected(aTarget)
224 nsresult
225 InitMetaData() MOZ_OVERRIDE
227 mMetaData.number_of_faces = 2;
228 AllocateFacesArray(2);
229 mMetaData.faces[0].id = 1;
230 mMetaData.faces[0].score = 2;
231 mMetaData.faces[0].rect[0] = 3;
232 mMetaData.faces[0].rect[1] = 4;
233 mMetaData.faces[0].rect[2] = 5;
234 mMetaData.faces[0].rect[3] = 6;
235 mMetaData.faces[0].left_eye[0] = 7;
236 mMetaData.faces[0].left_eye[1] = 8;
237 mMetaData.faces[0].right_eye[0] = 9;
238 mMetaData.faces[0].right_eye[1] = 10;
239 mMetaData.faces[0].mouth[0] = 11;
240 mMetaData.faces[0].mouth[1] = 12;
241 mMetaData.faces[1].id = 13;
242 mMetaData.faces[1].score = 14;
243 mMetaData.faces[1].rect[0] = 15;
244 mMetaData.faces[1].rect[1] = 16;
245 mMetaData.faces[1].rect[2] = 17;
246 mMetaData.faces[1].rect[3] = 18;
247 mMetaData.faces[1].left_eye[0] = 19;
248 mMetaData.faces[1].left_eye[1] = 20;
249 mMetaData.faces[1].right_eye[0] = 21;
250 mMetaData.faces[1].right_eye[1] = 22;
251 mMetaData.faces[1].mouth[0] = 23;
252 mMetaData.faces[1].mouth[1] = 24;
254 return NS_OK;
258 class OneFaceNoFeaturesDetected : public FaceDetected
260 public:
261 OneFaceNoFeaturesDetected(nsGonkCameraControl* aTarget)
262 : FaceDetected(aTarget)
265 nsresult
266 InitMetaData() MOZ_OVERRIDE
268 mMetaData.number_of_faces = 1;
269 AllocateFacesArray(1);
270 mMetaData.faces[0].id = 1;
271 // Test clamping 'score' to 100.
272 mMetaData.faces[0].score = 1000;
273 mMetaData.faces[0].rect[0] = 3;
274 mMetaData.faces[0].rect[1] = 4;
275 mMetaData.faces[0].rect[2] = 5;
276 mMetaData.faces[0].rect[3] = 6;
277 // Nullable values set to 'not-supported' specific values
278 mMetaData.faces[0].left_eye[0] = -2000;
279 mMetaData.faces[0].left_eye[1] = -2000;
280 // Test other 'not-supported' values as well. We treat
281 // anything outside the range [-1000, 1000] as invalid.
282 mMetaData.faces[0].right_eye[0] = 1001;
283 mMetaData.faces[0].right_eye[1] = -1001;
284 mMetaData.faces[0].mouth[0] = -2000;
285 mMetaData.faces[0].mouth[1] = 2000;
287 return NS_OK;
291 class NoFacesDetected : public FaceDetected
293 public:
294 NoFacesDetected(nsGonkCameraControl* aTarget)
295 : FaceDetected(aTarget)
298 nsresult
299 InitMetaData() MOZ_OVERRIDE
301 mMetaData.number_of_faces = 0;
302 mMetaData.faces = nullptr;
304 return NS_OK;
309 TestGonkCameraHardware::StartFaceDetection()
311 nsRefPtr<FaceDetected> faceDetected;
313 if (IsTestCase("face-detection-detected-one-face")) {
314 faceDetected = new OneFaceDetected(mTarget);
315 } else if (IsTestCase("face-detection-detected-two-faces")) {
316 faceDetected = new TwoFacesDetected(mTarget);
317 } else if (IsTestCase("face-detection-detected-one-face-no-features")) {
318 faceDetected = new OneFaceNoFeaturesDetected(mTarget);
319 } else if (IsTestCase("face-detection-no-faces-detected")) {
320 faceDetected = new NoFacesDetected(mTarget);
323 if (!faceDetected) {
324 return GonkCameraHardware::StartFaceDetection();
327 nsresult rv = NS_DispatchToCurrentThread(faceDetected);
328 if (NS_FAILED(rv)) {
329 DOM_CAMERA_LOGE("Failed to dispatch FaceDetected runnable (0x%08x)\n", rv);
330 return UNKNOWN_ERROR;
333 return OK;
337 TestGonkCameraHardware::StopFaceDetection()
339 if (IsTestCase("face-detection-detected-one-face") ||
340 IsTestCase("face-detection-detected-two-faces") ||
341 IsTestCase("face-detection-detected-one-face-no-features") ||
342 IsTestCase("face-detection-no-faces-detected"))
344 return OK;
347 return GonkCameraHardware::StopFaceDetection();
351 TestGonkCameraHardware::TakePicture()
353 class TakePictureFailure : public nsRunnable
355 public:
356 TakePictureFailure(nsGonkCameraControl* aTarget)
357 : mTarget(aTarget)
360 NS_IMETHODIMP
361 Run()
363 OnTakePictureError(mTarget);
364 return NS_OK;
367 protected:
368 nsGonkCameraControl* mTarget;
371 if (IsTestCase("take-picture-failure")) {
372 return TestCaseError(UNKNOWN_ERROR);
374 if (IsTestCase("take-picture-process-failure")) {
375 nsresult rv = NS_DispatchToCurrentThread(new TakePictureFailure(mTarget));
376 if (NS_SUCCEEDED(rv)) {
377 return OK;
379 DOM_CAMERA_LOGE("Failed to dispatch TakePictureFailure runnable (0x%08x)\n", rv);
380 return UNKNOWN_ERROR;
383 return GonkCameraHardware::TakePicture();
387 TestGonkCameraHardware::StartPreview()
389 if (IsTestCase("start-preview-failure")) {
390 return TestCaseError(UNKNOWN_ERROR);
393 return GonkCameraHardware::StartPreview();
397 TestGonkCameraHardware::StartAutoFocusMoving(bool aIsMoving)
399 class AutoFocusMoving : public nsRunnable
401 public:
402 AutoFocusMoving(nsGonkCameraControl* aTarget, bool aIsMoving)
403 : mTarget(aTarget)
404 , mIsMoving(aIsMoving)
407 NS_IMETHODIMP
408 Run()
410 OnAutoFocusMoving(mTarget, mIsMoving);
411 return NS_OK;
414 protected:
415 nsGonkCameraControl* mTarget;
416 bool mIsMoving;
419 nsresult rv = NS_DispatchToCurrentThread(new AutoFocusMoving(mTarget, aIsMoving));
420 if (NS_SUCCEEDED(rv)) {
421 return OK;
423 DOM_CAMERA_LOGE("Failed to dispatch AutoFocusMoving runnable (0x%08x)\n", rv);
424 return UNKNOWN_ERROR;
428 TestGonkCameraHardware::PushParameters(const GonkCameraParameters& aParams)
430 if (IsTestCase("push-parameters-failure")) {
431 return TestCaseError(UNKNOWN_ERROR);
434 nsString focusMode;
435 GonkCameraParameters& params = const_cast<GonkCameraParameters&>(aParams);
436 params.Get(CAMERA_PARAM_FOCUSMODE, focusMode);
437 if (focusMode.EqualsASCII("continuous-picture") ||
438 focusMode.EqualsASCII("continuous-video"))
440 if (IsTestCase("autofocus-moving-true")) {
441 return StartAutoFocusMoving(true);
442 } else if (IsTestCase("autofocus-moving-false")) {
443 return StartAutoFocusMoving(false);
447 return GonkCameraHardware::PushParameters(aParams);
450 nsresult
451 TestGonkCameraHardware::PullParameters(GonkCameraParameters& aParams)
453 if (IsTestCase("pull-parameters-failure")) {
454 return static_cast<nsresult>(TestCaseError(UNKNOWN_ERROR));
457 String8 s = mCamera->getParameters();
458 nsCString extra = GetExtraParameters();
459 if (!extra.IsEmpty()) {
460 s += ";";
461 s += extra.get();
464 return aParams.Unflatten(s);
468 TestGonkCameraHardware::StartRecording()
470 if (IsTestCase("start-recording-failure")) {
471 return TestCaseError(UNKNOWN_ERROR);
474 return GonkCameraHardware::StartRecording();
478 TestGonkCameraHardware::StopRecording()
480 if (IsTestCase("stop-recording-failure")) {
481 return TestCaseError(UNKNOWN_ERROR);
484 return GonkCameraHardware::StopRecording();
488 TestGonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
490 if (IsTestCase("set-listener-failure")) {
491 return TestCaseError(UNKNOWN_ERROR);
494 return GonkCameraHardware::SetListener(aListener);
498 TestGonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
500 if (IsTestCase("store-metadata-in-buffers-failure")) {
501 return TestCaseError(UNKNOWN_ERROR);
504 return GonkCameraHardware::StoreMetaDataInBuffers(aEnabled);