Bug 1037322 - change CameraConfiguration default mode to 'unspecified' r=dhylands,khuey
authorMike Habicher <mikeh@mozilla.com>
Tue, 05 Aug 2014 13:20:31 -0400
changeset 197900 a278dc70b5f89426926502066fbedc41c1314513
parent 197890 53435d8f48013d3a28dfadc7abd598ce1721a1fe
child 197901 1bcdfe24909e8739d44e1db857f0717f97178969
push id27255
push userkwierso@gmail.com
push dateTue, 05 Aug 2014 23:36:26 +0000
treeherdermozilla-central@e66e1130da31 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands, khuey
bugs1037322
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1037322 - change CameraConfiguration default mode to 'unspecified' r=dhylands,khuey
dom/camera/DOMCameraControl.cpp
dom/camera/GonkCameraControl.cpp
dom/camera/test/mochitest.ini
dom/camera/test/test_bug1037322.html
dom/webidl/CameraManager.webidl
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -163,50 +163,64 @@ nsDOMCameraControl::nsDOMCameraControl(u
 
   SetIsDOMBinding();
 
   nsRefPtr<DOMCameraConfiguration> initialConfig =
     new DOMCameraConfiguration(aInitialConfig);
 
   // Create and initialize the underlying camera.
   ICameraControl::Configuration config;
+  bool haveInitialConfig = false;
+  nsresult rv;
 
   switch (aInitialConfig.mMode) {
     case CameraMode::Picture:
       config.mMode = ICameraControl::kPictureMode;
+      haveInitialConfig = true;
       break;
 
     case CameraMode::Video:
       config.mMode = ICameraControl::kVideoMode;
+      haveInitialConfig = true;
+      break;
+
+    case CameraMode::Unspecified:
       break;
 
     default:
       MOZ_ASSERT_UNREACHABLE("Unanticipated camera mode!");
+      break;
   }
 
-  config.mPreviewSize.width = aInitialConfig.mPreviewSize.mWidth;
-  config.mPreviewSize.height = aInitialConfig.mPreviewSize.mHeight;
-  config.mRecorderProfile = aInitialConfig.mRecorderProfile;
+  if (haveInitialConfig) {
+    config.mPreviewSize.width = aInitialConfig.mPreviewSize.mWidth;
+    config.mPreviewSize.height = aInitialConfig.mPreviewSize.mHeight;
+    config.mRecorderProfile = aInitialConfig.mRecorderProfile;
+  }
 
   mCameraControl = ICameraControl::Create(aCameraId);
   mCurrentConfiguration = initialConfig.forget();
 
   // Attach our DOM-facing media stream to our viewfinder stream.
   mStream = mInput;
   MOZ_ASSERT(mWindow, "Shouldn't be created with a null window!");
   if (mWindow->GetExtantDoc()) {
     CombineWithPrincipal(mWindow->GetExtantDoc()->NodePrincipal());
   }
 
   // Register a listener for camera events.
   mListener = new DOMCameraControlListener(this, mInput);
   mCameraControl->AddListener(mListener);
 
   // Start the camera...
-  nsresult rv = mCameraControl->Start(&config);
+  if (haveInitialConfig) {
+    rv = mCameraControl->Start(&config);
+  } else {
+    rv = mCameraControl->Start();
+  }
   if (NS_FAILED(rv)) {
     mListener->OnUserError(DOMCameraControlListener::kInStartCamera, rv);
   }
 }
 
 nsDOMCameraControl::~nsDOMCameraControl()
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -117,17 +117,21 @@ nsGonkCameraControl::StartImpl(const Con
     if (NS_WARN_IF(NS_FAILED(rv))) {
       // The initial configuration failed, close up the hardware
       StopImpl();
       return rv;
     }
   }
 
   OnHardwareStateChange(CameraControlListener::kHardwareOpen);
-  return StartPreviewImpl();
+  if (aInitialConfig) {
+    return StartPreviewImpl();
+  }
+
+  return NS_OK;
 }
 
 nsresult
 nsGonkCameraControl::Initialize()
 {
   if (mCameraHw.get()) {
     DOM_CAMERA_LOGI("Camera %d already connected (this=%p)\n", mCameraId, this);
     return NS_ERROR_ALREADY_INITIALIZED;
@@ -252,16 +256,21 @@ nsGonkCameraControl::SetConfigurationInt
 }
 
 nsresult
 nsGonkCameraControl::SetConfigurationImpl(const Configuration& aConfig)
 {
   DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
   MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
 
+  if (aConfig.mMode == kUnspecifiedMode) {
+    DOM_CAMERA_LOGW("Can't set camera mode to 'unspecified', ignoring\n");
+    return NS_ERROR_INVALID_ARG;
+  }
+
   // Stop any currently running preview
   nsresult rv = PausePreview();
   if (NS_FAILED(rv)) {
     DOM_CAMERA_LOGW("PausePreview() in SetConfigurationImpl() failed (0x%x)\n", rv);
     if (rv == NS_ERROR_NOT_INITIALIZED) {
       // If there no hardware available, nothing else we try will work,
       // so bail out here.
       return rv;
--- a/dom/camera/test/mochitest.ini
+++ b/dom/camera/test/mochitest.ini
@@ -6,8 +6,9 @@ support-files = camera_common.js
 [test_camera_3.html]
 [test_camera_hardware_init_failure.html]
 [test_camera_hardware_failures.html]
 [test_bug975472.html]
 [test_camera_fake_parameters.html]
 [test_camera_hardware_face_detection.html]
 [test_camera_hardware_auto_focus_moving_cb.html]
 [test_bug1022766.html]
+[test_bug1037322.html]
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/test_bug1037322.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for bug 1037322</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 whichCamera = navigator.mozCameras.getListOfCameras()[0];
+var config = {
+  mode: 'picture',
+  recorderProfile: 'cif',
+  previewSize: {
+    width: 352,
+    height: 288
+  }
+};
+
+function onError(e) {
+  ok(false, "Error: " + JSON.stringify(e));
+}
+
+var Camera = {
+  cameraObj: null,
+
+  get viewfinder() {
+    return document.getElementById('viewfinder');
+  },
+
+  start: function test_start() {
+    function setConfig_onSuccess(cfg) {
+      // Check our specific configuration
+      ok(cfg.mode === config.mode, "Configured mode = " + cfg.mode);
+      ok(cfg.previewSize.width === config.previewSize.width &&
+         cfg.previewSize.height === config.previewSize.height,
+         "Configured preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
+      ok(cfg.recorderProfile === config.recorderProfile,
+         "Configured recorder profile = '" + cfg.recorderProfile + "'");
+
+      SimpleTest.finish();
+    }
+
+    function getCamera_onSuccess(camera, cfg) {
+      Camera.cameraObj = camera;
+      Camera.viewfinder.mozSrcObject = camera;
+      Camera.viewfinder.play();
+
+      // Check the default configuration
+      ok(cfg.mode === "unspecified", "Initial mode = " + cfg.mode);
+      ok(cfg.previewSize.width === 0 && cfg.previewSize.height === 0,
+         "Initial preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
+      ok(cfg.recorderProfile === "",
+         "Initial recorder profile = '" + cfg.recorderProfile + "'");
+
+      // Apply our specific configuration
+      camera.setConfiguration(config, setConfig_onSuccess, onError);
+    }
+
+    navigator.mozCameras.getCamera(whichCamera, {}, getCamera_onSuccess, onError);
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener('beforeunload', function() {
+  Camera.viewfinder.mozSrcObject = null;
+  if (Camera.cameraObj) {
+    Camera.cameraObj.release();
+    Camera.cameraObj = null;
+  }
+});
+
+Camera.start();
+
+</script>
+</body>
+
+</html>
--- a/dom/webidl/CameraManager.webidl
+++ b/dom/webidl/CameraManager.webidl
@@ -1,32 +1,32 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-enum CameraMode { "picture", "video" };
+enum CameraMode { "unspecified", "picture", "video" };
 
 /* Used for the dimensions of a captured picture,
    a preview stream, a video capture stream, etc. */
 dictionary CameraSize
 {
   unsigned long width = 0;
   unsigned long height = 0;
 };
 
 /* Pre-emptive camera configuration options. */
 dictionary CameraConfiguration
 {
-  CameraMode mode = "picture";
+  CameraMode mode = "unspecified";
   CameraSize previewSize = null;
-  DOMString recorderProfile = "cif";  // or some other recording profile
-                                      // supported by the CameraControl
+  DOMString recorderProfile = ""; // one of the profiles reported by
+                                  // CameraControl.capabilities.recorderProfiles
 };
 
 callback CameraErrorCallback = void (DOMString error);
 
 callback GetCameraCallback = void (CameraControl camera,
                                    CameraConfiguration configuration);
 
 [Func="nsDOMCameraManager::HasSupport"]