Bug 986024 - Expose resumeContinuousFocus() method to DOM/JS. r=bz, r=dhylands, a=1.4+
authorMike Habicher <mikeh@mozilla.com>
Thu, 17 Apr 2014 10:41:39 -0400
changeset 185692 df67d32e6282846029b8ff39891786d544a22f1b
parent 185691 ac0dfb5a046225e27c84225bcff13afb9e027589
child 185693 ea3724cf62eaee2c4aca5f33df5e0d300b2984f9
push id5736
push userryanvm@gmail.com
push dateThu, 17 Apr 2014 14:41:46 +0000
treeherdermozilla-aurora@ea3724cf62ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, dhylands, 1
bugs986024
milestone30.0a2
Bug 986024 - Expose resumeContinuousFocus() method to DOM/JS. r=bz, r=dhylands, a=1.4+
dom/camera/CameraControlImpl.cpp
dom/camera/CameraControlImpl.h
dom/camera/CameraControlListener.h
dom/camera/DOMCameraControl.cpp
dom/camera/DOMCameraControl.h
dom/camera/FallbackCameraControl.cpp
dom/camera/GonkCameraControl.cpp
dom/camera/GonkCameraControl.h
dom/camera/GonkCameraHwMgr.cpp
dom/camera/GonkCameraHwMgr.h
dom/camera/ICameraControl.h
dom/webidl/CameraControl.webidl
--- a/dom/camera/CameraControlImpl.cpp
+++ b/dom/camera/CameraControlImpl.cpp
@@ -249,16 +249,17 @@ CameraControlImpl::OnError(CameraControl
     "StopCamera",
     "AutoFocus",
     "TakePicture",
     "StartRecording",
     "StopRecording",
     "SetConfiguration",
     "StartPreview",
     "StopPreview",
+    "ResumeContinuousFocus",
     "Unspecified"
   };
   if (static_cast<unsigned int>(aError) < sizeof(error) / sizeof(error[0]) &&
     static_cast<unsigned int>(aContext) < sizeof(context) / sizeof(context[0])) {
     DOM_CAMERA_LOGW("CameraControlImpl::OnError : aContext='%s' (%u), aError='%s' (%u)\n",
       context[aContext], aContext, error[aError], aError);
   } else {
     DOM_CAMERA_LOGE("CameraControlImpl::OnError : aContext=%u, aError=%d\n",
@@ -373,40 +374,35 @@ CameraControlImpl::SetConfiguration(cons
     Configuration mConfig;
   };
 
   return mCameraThread->Dispatch(
     new Message(this, CameraControlListener::kInSetConfiguration, aConfig), NS_DISPATCH_NORMAL);
 }
 
 nsresult
-CameraControlImpl::AutoFocus(bool aCancelExistingCall)
+CameraControlImpl::AutoFocus()
 {
   class Message : public ControlMessage
   {
   public:
     Message(CameraControlImpl* aCameraControl,
-            CameraControlListener::CameraErrorContext aContext,
-            bool aCancelExistingCall)
+            CameraControlListener::CameraErrorContext aContext)
       : ControlMessage(aCameraControl, aContext)
-      , mCancelExistingCall(aCancelExistingCall)
     { }
 
     nsresult
     RunImpl() MOZ_OVERRIDE
     {
-      return mCameraControl->AutoFocusImpl(mCancelExistingCall);
+      return mCameraControl->AutoFocusImpl();
     }
-
-  protected:
-    bool mCancelExistingCall;
   };
 
   return mCameraThread->Dispatch(
-    new Message(this, CameraControlListener::kInAutoFocus, aCancelExistingCall), NS_DISPATCH_NORMAL);
+    new Message(this, CameraControlListener::kInAutoFocus), NS_DISPATCH_NORMAL);
 }
 
 nsresult
 CameraControlImpl::TakePicture()
 {
   class Message : public ControlMessage
   {
   public:
@@ -527,16 +523,38 @@ CameraControlImpl::StopPreview()
     }
   };
 
   return mCameraThread->Dispatch(
     new Message(this, CameraControlListener::kInStopPreview), NS_DISPATCH_NORMAL);
 }
 
 nsresult
+CameraControlImpl::ResumeContinuousFocus()
+{
+  class Message : public ControlMessage
+  {
+  public:
+    Message(CameraControlImpl* aCameraControl,
+            CameraControlListener::CameraErrorContext aContext)
+      : ControlMessage(aCameraControl, aContext)
+    { }
+
+    nsresult
+    RunImpl() MOZ_OVERRIDE
+    {
+      return mCameraControl->ResumeContinuousFocusImpl();
+    }
+  };
+
+  return mCameraThread->Dispatch(
+    new Message(this, CameraControlListener::kInResumeContinuousFocus), NS_DISPATCH_NORMAL);
+}
+
+nsresult
 CameraControlImpl::Stop()
 {
   class Message : public ControlMessage
   {
   public:
     Message(CameraControlImpl* aCameraControl,
             CameraControlListener::CameraErrorContext aContext)
       : ControlMessage(aCameraControl, aContext)
--- a/dom/camera/CameraControlImpl.h
+++ b/dom/camera/CameraControlImpl.h
@@ -37,21 +37,22 @@ public:
   virtual void RemoveListener(CameraControlListener* aListener) MOZ_OVERRIDE;
 
   virtual nsresult Start(const Configuration* aConfig = nullptr) MOZ_OVERRIDE;
   virtual nsresult Stop() MOZ_OVERRIDE;
 
   virtual nsresult SetConfiguration(const Configuration& aConfig) MOZ_OVERRIDE;
   virtual nsresult StartPreview() MOZ_OVERRIDE;
   virtual nsresult StopPreview() MOZ_OVERRIDE;
-  virtual nsresult AutoFocus(bool aCancelExistingCall) MOZ_OVERRIDE;
+  virtual nsresult AutoFocus() MOZ_OVERRIDE;
   virtual nsresult TakePicture() MOZ_OVERRIDE;
   virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor,
                                   const StartRecordingOptions* aOptions) MOZ_OVERRIDE;
   virtual nsresult StopRecording() MOZ_OVERRIDE;
+  virtual nsresult ResumeContinuousFocus() MOZ_OVERRIDE;
 
   already_AddRefed<RecorderProfileManager> GetRecorderProfileManager();
   uint32_t GetCameraId() { return mCameraId; }
 
   virtual void Shutdown() MOZ_OVERRIDE;
 
   void OnShutter();
   void OnClosed();
@@ -92,21 +93,22 @@ protected:
   class ControlMessage;
   class ListenerMessage;
 
   virtual nsresult StartImpl(const Configuration* aConfig = nullptr) = 0;
   virtual nsresult StopImpl() = 0;
   virtual nsresult SetConfigurationImpl(const Configuration& aConfig) = 0;
   virtual nsresult StartPreviewImpl() = 0;
   virtual nsresult StopPreviewImpl() = 0;
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) = 0;
+  virtual nsresult AutoFocusImpl() = 0;
   virtual nsresult TakePictureImpl() = 0;
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
                                       const StartRecordingOptions* aOptions) = 0;
   virtual nsresult StopRecordingImpl() = 0;
+  virtual nsresult ResumeContinuousFocusImpl() = 0;
   virtual nsresult PushParametersImpl() = 0;
   virtual nsresult PullParametersImpl() = 0;
   virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() = 0;
 
   void OnShutterInternal();
   void OnClosedInternal();
 
   uint32_t mCameraId;
--- a/dom/camera/CameraControlListener.h
+++ b/dom/camera/CameraControlListener.h
@@ -83,16 +83,17 @@ public:
     kInStopCamera,
     kInAutoFocus,
     kInTakePicture,
     kInStartRecording,
     kInStopRecording,
     kInSetConfiguration,
     kInStartPreview,
     kInStopPreview,
+    kInResumeContinuousFocus,
     kInUnspecified
   };
   enum CameraError
   {
     kErrorApiFailed,
     kErrorInitFailed,
     kErrorInvalidConfiguration,
     kErrorServiceFailed,
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -810,60 +810,82 @@ nsDOMCameraControl::SetConfiguration(con
   mSetConfigurationOnErrorCb = nullptr;
   if (aOnError.WasPassed()) {
     mSetConfigurationOnErrorCb = &aOnError.Value();
   }
 
   aRv = mCameraControl->SetConfiguration(config);
 }
 
+class ImmediateErrorCallback : public nsRunnable
+{
+public:
+  ImmediateErrorCallback(CameraErrorCallback* aCallback, const nsAString& aMessage)
+    : mCallback(aCallback)
+    , mMessage(aMessage)
+  { }
+  
+  NS_IMETHODIMP
+  Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    ErrorResult ignored;
+    mCallback->Call(mMessage, ignored);
+    return NS_OK;
+  }
+
+protected:
+  nsCOMPtr<CameraErrorCallback> mCallback;
+  nsString mMessage;
+};
+
+
 void
 nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess,
                               const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
                               ErrorResult& aRv)
 {
   MOZ_ASSERT(mCameraControl);
 
-  nsCOMPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb.forget();
-  bool cancel = false;
+  nsCOMPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb;
   if (cb) {
-    // we have a callback, which means we're already in the process of
-    // auto-focusing--cancel the old callback
-    nsCOMPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
-    if (ecb) {
-      ErrorResult ignored;
-      ecb->Call(NS_LITERAL_STRING("Interrupted"), ignored);
+    if (aOnError.WasPassed()) {
+      // There is already a call to AutoFocus() in progress, abort this new one
+      // and invoke the error callback (if one was passed in).
+      NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
+                              NS_LITERAL_STRING("AutoFocusAlreadyInProgress")));
     }
-    cancel = true;
+    aRv = NS_ERROR_FAILURE;
+    return;
   }
 
   mAutoFocusOnSuccessCb = &aOnSuccess;
   mAutoFocusOnErrorCb = nullptr;
   if (aOnError.WasPassed()) {
     mAutoFocusOnErrorCb = &aOnError.Value();
   }
 
-  aRv = mCameraControl->AutoFocus(cancel);
+  aRv = mCameraControl->AutoFocus();
 }
 
 void
 nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
                                 CameraTakePictureCallback& aOnSuccess,
                                 const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
                                 ErrorResult& aRv)
 {
   MOZ_ASSERT(mCameraControl);
 
   nsCOMPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
   if (cb) {
-    // There is already a call to TakePicture() in progress, abort this one and
-    //  invoke the error callback (if one was passed in).
     if (aOnError.WasPassed()) {
-      ErrorResult ignored;
-      aOnError.Value().Call(NS_LITERAL_STRING("TakePictureAlreadyInProgress"), ignored);
+      // There is already a call to TakePicture() in progress, abort this new
+      // one and invoke the error callback (if one was passed in).
+      NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
+                              NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
     }
     aRv = NS_ERROR_FAILURE;
     return;
   }
 
   {
     ICameraControlParameterSetAutoEnter batch(mCameraControl);
 
@@ -911,16 +933,23 @@ nsDOMCameraControl::ReleaseHardware(cons
   if (aOnError.WasPassed()) {
     mReleaseOnErrorCb = &aOnError.Value();
   }
 
   aRv = mCameraControl->Stop();
 }
 
 void
+nsDOMCameraControl::ResumeContinuousFocus(ErrorResult& aRv)
+{
+  MOZ_ASSERT(mCameraControl);
+  aRv = mCameraControl->ResumeContinuousFocus();
+}
+
+void
 nsDOMCameraControl::Shutdown()
 {
   DOM_CAMERA_LOGI("%s:%d\n", __func__, __LINE__);
   MOZ_ASSERT(mCameraControl);
 
   // Remove any pending solicited event handlers; these
   // reference our window object, which in turn references
   // us. If we don't remove them, we can leak DOM objects.
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -110,16 +110,17 @@ public:
                       dom::CameraStartRecordingCallback& aOnSuccess,
                       const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
                       ErrorResult& aRv);
   void StopRecording(ErrorResult& aRv);
   void ResumePreview(ErrorResult& aRv);
   void ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
                        const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
                        ErrorResult& aRv);
+  void ResumeContinuousFocus(ErrorResult& aRv);
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsDOMCameraControl();
 
   class DOMCameraConfiguration : public dom::CameraConfiguration
   {
--- a/dom/camera/FallbackCameraControl.cpp
+++ b/dom/camera/FallbackCameraControl.cpp
@@ -52,24 +52,25 @@ public:
   virtual nsresult Get(uint32_t aKey, nsTArray<double>& aValues) MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
 
   nsresult PushParameters() { return NS_ERROR_FAILURE; }
   nsresult PullParameters() { return NS_ERROR_FAILURE; }
 
 protected:
   ~FallbackCameraControl();
 
-  virtual nsresult StartPreviewImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult StopPreviewImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) { return NS_ERROR_FAILURE; }
-  virtual nsresult TakePictureImpl() { return NS_ERROR_FAILURE; }
+  virtual nsresult StartPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult StopPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult AutoFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult TakePictureImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
-                                      const StartRecordingOptions* aOptions = nullptr)
+                                      const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE
                                         { return NS_ERROR_FAILURE; }
-  virtual nsresult StopRecordingImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult PushParametersImpl() { return NS_ERROR_FAILURE; }
-  virtual nsresult PullParametersImpl() { return NS_ERROR_FAILURE; }
-  virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() { return nullptr; }
+  virtual nsresult StopRecordingImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult PushParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual nsresult PullParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; }
+  virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE { return nullptr; }
 
 private:
   FallbackCameraControl(const FallbackCameraControl&) MOZ_DELETE;
   FallbackCameraControl& operator=(const FallbackCameraControl&) MOZ_DELETE;
 };
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -526,25 +526,22 @@ nsGonkCameraControl::PausePreview()
   DOM_CAMERA_LOGI("Pausing preview (this=%p)\n", this);
 
   mCameraHw->StopPreview();
   OnPreviewStateChange(CameraControlListener::kPreviewPaused);
   return NS_OK;
 }
 
 nsresult
-nsGonkCameraControl::AutoFocusImpl(bool aCancelExistingCall)
+nsGonkCameraControl::AutoFocusImpl()
 {
   MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
   RETURN_IF_NO_CAMERA_HW();
-  if (aCancelExistingCall) {
-    if (mCameraHw.get()) {
-      mCameraHw->CancelAutoFocus();
-    }
-  }
+
+  DOM_CAMERA_LOGI("Starting auto focus\n");
 
   if (mCameraHw->AutoFocus() != OK) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
@@ -920,16 +917,33 @@ nsGonkCameraControl::StopRecordingImpl()
   mRecorder->stop();
   mRecorder = nullptr;
   OnRecorderStateChange(CameraControlListener::kRecorderStopped);
 
   // notify DeviceStorage that the new video file is closed and ready
   return NS_DispatchToMainThread(new RecordingComplete(mVideoFile), NS_DISPATCH_NORMAL);
 }
 
+nsresult
+nsGonkCameraControl::ResumeContinuousFocusImpl()
+{
+  MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
+  RETURN_IF_NO_CAMERA_HW();
+
+  DOM_CAMERA_LOGI("Resuming continuous autofocus\n");
+
+  // see
+  // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_PICTURE
+  if (NS_WARN_IF(mCameraHw->CancelAutoFocus() != OK)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return NS_OK;
+}
+
 void
 nsGonkCameraControl::OnAutoFocusComplete(bool aSuccess)
 {
   class AutoFocusComplete : public nsRunnable
   {
   public:
     AutoFocusComplete(nsGonkCameraControl* aCameraControl, bool aSuccess)
       : mCameraControl(aCameraControl)
--- a/dom/camera/GonkCameraControl.h
+++ b/dom/camera/GonkCameraControl.h
@@ -98,21 +98,22 @@ protected:
   nsresult SetConfigurationInternal(const Configuration& aConfig);
   nsresult SetPictureConfiguration(const Configuration& aConfig);
   nsresult SetVideoConfiguration(const Configuration& aConfig);
 
   template<class T> nsresult SetAndPush(uint32_t aKey, const T& aValue);
 
   virtual nsresult StartPreviewImpl() MOZ_OVERRIDE;
   virtual nsresult StopPreviewImpl() MOZ_OVERRIDE;
-  virtual nsresult AutoFocusImpl(bool aCancelExistingCall) MOZ_OVERRIDE;
+  virtual nsresult AutoFocusImpl() MOZ_OVERRIDE;
   virtual nsresult TakePictureImpl() MOZ_OVERRIDE;
   virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor,
                                       const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE;
   virtual nsresult StopRecordingImpl() MOZ_OVERRIDE;
+  virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE;
   virtual nsresult PushParametersImpl() MOZ_OVERRIDE;
   virtual nsresult PullParametersImpl() MOZ_OVERRIDE;
   virtual already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl() MOZ_OVERRIDE;
   already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
 
   nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
   nsresult SetupVideoMode(const nsAString& aProfile);
   nsresult SetPreviewSize(const Size& aSize);
--- a/dom/camera/GonkCameraHwMgr.cpp
+++ b/dom/camera/GonkCameraHwMgr.cpp
@@ -268,21 +268,21 @@ GonkCameraHardware::GetSensorOrientation
 
 int
 GonkCameraHardware::AutoFocus()
 {
   DOM_CAMERA_LOGI("%s\n", __func__);
   return mCamera->autoFocus();
 }
 
-void
+int
 GonkCameraHardware::CancelAutoFocus()
 {
   DOM_CAMERA_LOGI("%s\n", __func__);
-  mCamera->cancelAutoFocus();
+  return mCamera->cancelAutoFocus();
 }
 
 int
 GonkCameraHardware::TakePicture()
 {
   return mCamera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
 }
 
--- a/dom/camera/GonkCameraHwMgr.h
+++ b/dom/camera/GonkCameraHwMgr.h
@@ -73,17 +73,17 @@ public:
    */
   enum {
     RAW_SENSOR_ORIENTATION,
     OFFSET_SENSOR_ORIENTATION
   };
   virtual int      GetSensorOrientation(uint32_t aType = RAW_SENSOR_ORIENTATION);
 
   virtual int      AutoFocus();
-  virtual void     CancelAutoFocus();
+  virtual int      CancelAutoFocus();
   virtual int      TakePicture();
   virtual void     CancelTakePicture();
   virtual int      StartPreview();
   virtual void     StopPreview();
   virtual int      PushParameters(const mozilla::GonkCameraParameters& aParams);
   virtual int      PushParameters(const CameraParameters& aParams);
   virtual nsresult PullParameters(mozilla::GonkCameraParameters& aParams);
   virtual void     PullParameters(CameraParameters& aParams);
--- a/dom/camera/ICameraControl.h
+++ b/dom/camera/ICameraControl.h
@@ -126,21 +126,22 @@ public:
 
   virtual nsresult SetConfiguration(const Configuration& aConfig) = 0;
 
   virtual void AddListener(CameraControlListener* aListener) = 0;
   virtual void RemoveListener(CameraControlListener* aListener) = 0;
 
   virtual nsresult StartPreview() = 0;
   virtual nsresult StopPreview() = 0;
-  virtual nsresult AutoFocus(bool aCancelExistingCall) = 0;
+  virtual nsresult AutoFocus() = 0;
   virtual nsresult TakePicture() = 0;
   virtual nsresult StartRecording(DeviceStorageFileDescriptor *aFileDescriptor,
                                   const StartRecordingOptions* aOptions = nullptr) = 0;
   virtual nsresult StopRecording() = 0;
+  virtual nsresult ResumeContinuousFocus() = 0;
 
   virtual nsresult Set(uint32_t aKey, const nsAString& aValue) = 0;
   virtual nsresult Get(uint32_t aKey, nsAString& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, double aValue) = 0;
   virtual nsresult Get(uint32_t aKey, double& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, int32_t aValue) = 0;
   virtual nsresult Get(uint32_t aKey, int32_t& aValue) = 0;
   virtual nsresult Set(uint32_t aKey, int64_t aValue) = 0;
--- a/dom/webidl/CameraControl.webidl
+++ b/dom/webidl/CameraControl.webidl
@@ -329,9 +329,23 @@ interface CameraControl : MediaStream
      the WebIDL compiler throws: "WebIDL.WebIDLError: error: Dictionary
      argument or union argument containing a dictionary not followed by
      a required argument must be optional"
   */
   [Throws]
   void setConfiguration(optional CameraConfiguration configuration,
                         optional CameraSetConfigurationCallback onSuccess,
                         optional CameraErrorCallback onError);
+
+  /* if focusMode is set to either 'continuous-picture' or 'continuous-video',
+     then calling autoFocus() will trigger its onSuccess callback immediately
+     if the camera was either successfully focused, or if no focus could be
+     acquired; if the focus acquisition is still in progress, the onSuccess
+     callback will be invoked later, its argument indicating success or
+     failure.
+
+     once autoFocus() is called with a continuous autofocus mode set, the
+     continuous autofocus process is stopped and focus is locked in the
+     current state until this method is called.
+  */
+  [Throws]
+  void resumeContinuousFocus();
 };