dom/camera/DOMCameraControlListener.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "DOMCameraControlListener.h"
     6 #include "nsThreadUtils.h"
     7 #include "nsDOMFile.h"
     8 #include "CameraCommon.h"
     9 #include "DOMCameraControl.h"
    10 #include "CameraPreviewMediaStream.h"
    11 #include "mozilla/dom/CameraManagerBinding.h"
    13 using namespace mozilla;
    14 using namespace mozilla::dom;
    16 DOMCameraControlListener::DOMCameraControlListener(nsDOMCameraControl* aDOMCameraControl,
    17                                                    CameraPreviewMediaStream* aStream)
    18   : mDOMCameraControl(new nsMainThreadPtrHolder<nsDOMCameraControl>(aDOMCameraControl))
    19   , mStream(aStream)
    20 {
    21   DOM_CAMERA_LOGT("%s:%d : this=%p, camera=%p, stream=%p\n",
    22     __func__, __LINE__, this, aDOMCameraControl, aStream);
    23 }
    25 DOMCameraControlListener::~DOMCameraControlListener()
    26 {
    27   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
    28 }
    30 // Boilerplate callback runnable
    31 class DOMCameraControlListener::DOMCallback : public nsRunnable
    32 {
    33 public:
    34   DOMCallback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl)
    35     : mDOMCameraControl(aDOMCameraControl)
    36   {
    37     MOZ_COUNT_CTOR(DOMCameraControlListener::DOMCallback);
    38   }
    39   virtual ~DOMCallback()
    40   {
    41     MOZ_COUNT_DTOR(DOMCameraControlListener::DOMCallback);
    42   }
    44   virtual void RunCallback(nsDOMCameraControl* aDOMCameraControl) = 0;
    46   NS_IMETHOD
    47   Run() MOZ_OVERRIDE
    48   {
    49     MOZ_ASSERT(NS_IsMainThread());
    51     nsRefPtr<nsDOMCameraControl> camera = mDOMCameraControl.get();
    52     if (camera) {
    53       RunCallback(camera);
    54     }
    55     return NS_OK;
    56   }
    58 protected:
    59   nsMainThreadPtrHandle<nsDOMCameraControl> mDOMCameraControl;
    60 };
    62 // Specific callback handlers
    63 void
    64 DOMCameraControlListener::OnHardwareStateChange(HardwareState aState)
    65 {
    66   class Callback : public DOMCallback
    67   {
    68   public:
    69     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
    70              HardwareState aState)
    71       : DOMCallback(aDOMCameraControl)
    72       , mState(aState)
    73     { }
    75     void
    76     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
    77     {
    78       aDOMCameraControl->OnHardwareStateChange(mState);
    79     }
    81   protected:
    82     HardwareState mState;
    83   };
    85   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aState));
    86 }
    88 void
    89 DOMCameraControlListener::OnPreviewStateChange(PreviewState aState)
    90 {
    91   class Callback : public DOMCallback
    92   {
    93   public:
    94     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
    95              PreviewState aState)
    96       : DOMCallback(aDOMCameraControl)
    97       , mState(aState)
    98     { }
   100     void
   101     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   102     {
   103       aDOMCameraControl->OnPreviewStateChange(mState);
   104     }
   106   protected:
   107     PreviewState mState;
   108   };
   110   switch (aState) {
   111     case kPreviewStopped:
   112       // Clear the current frame right away, without dispatching a
   113       //  runnable. This is an ugly coupling between the camera's
   114       //  SurfaceTextureClient and the MediaStream/ImageContainer,
   115       //  but without it, the preview can fail to start.
   116       DOM_CAMERA_LOGI("Preview stopped, clearing current frame\n");
   117       mStream->ClearCurrentFrame();
   118       break;
   120     case kPreviewPaused:
   121       // In the paused state, we still want to reflect the change
   122       //  in preview state, but we don't want to clear the current
   123       //  frame as above, since doing so seems to cause genlock
   124       //  problems when we restart the preview. See bug 957749.
   125       DOM_CAMERA_LOGI("Preview paused\n");
   126       break;
   128     case kPreviewStarted:
   129       DOM_CAMERA_LOGI("Preview started\n");
   130       break;
   132     default:
   133       DOM_CAMERA_LOGE("Unknown preview state %d\n", aState);
   134       MOZ_ASSUME_UNREACHABLE("Invalid preview state");
   135       return;
   136   }
   137   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aState));
   138 }
   140 void
   141 DOMCameraControlListener::OnRecorderStateChange(RecorderState aState,
   142                                                 int32_t aStatus, int32_t aTrackNum)
   143 {
   144   class Callback : public DOMCallback
   145   {
   146   public:
   147     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   148              RecorderState aState,
   149              int32_t aStatus,
   150              int32_t aTrackNum)
   151       : DOMCallback(aDOMCameraControl)
   152       , mState(aState)
   153       , mStatus(aStatus)
   154       , mTrackNum(aTrackNum)
   155     { }
   157     void
   158     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   159     {
   160       aDOMCameraControl->OnRecorderStateChange(mState, mStatus, mTrackNum);
   161     }
   163   protected:
   164     RecorderState mState;
   165     int32_t mStatus;
   166     int32_t mTrackNum;
   167   };
   169   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aState, aStatus, aTrackNum));
   170 }
   172 void
   173 DOMCameraControlListener::OnConfigurationChange(const CameraListenerConfiguration& aConfiguration)
   174 {
   175   class Callback : public DOMCallback
   176   {
   177   public:
   178     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   179              const CameraListenerConfiguration& aConfiguration)
   180       : DOMCallback(aDOMCameraControl)
   181       , mConfiguration(aConfiguration)
   182     { }
   184     void
   185     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   186     {
   187       nsRefPtr<nsDOMCameraControl::DOMCameraConfiguration> config =
   188         new nsDOMCameraControl::DOMCameraConfiguration();
   190       switch (mConfiguration.mMode) {
   191         case ICameraControl::kVideoMode:
   192           config->mMode = CameraMode::Video;
   193           break;
   195         case ICameraControl::kPictureMode:
   196           config->mMode = CameraMode::Picture;
   197           break;
   199         default:
   200           DOM_CAMERA_LOGI("Camera mode still unspecified, nothing to do\n");
   201           return;
   202       }
   204       // Map CameraControl parameters to their DOM-facing equivalents
   205       config->mRecorderProfile = mConfiguration.mRecorderProfile;
   206       config->mPreviewSize.mWidth = mConfiguration.mPreviewSize.width;
   207       config->mPreviewSize.mHeight = mConfiguration.mPreviewSize.height;
   208       config->mMaxMeteringAreas = mConfiguration.mMaxMeteringAreas;
   209       config->mMaxFocusAreas = mConfiguration.mMaxFocusAreas;
   211       aDOMCameraControl->OnConfigurationChange(config);
   212     }
   214   protected:
   215     const CameraListenerConfiguration mConfiguration;
   216   };
   218   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aConfiguration));
   219 }
   221 void
   222 DOMCameraControlListener::OnAutoFocusMoving(bool aIsMoving)
   223 {
   224   class Callback : public DOMCallback
   225   {
   226   public:
   227     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl, bool aIsMoving)
   228       : DOMCallback(aDOMCameraControl)
   229       , mIsMoving(aIsMoving)
   230     { }
   232     void
   233     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   234     {
   235       aDOMCameraControl->OnAutoFocusMoving(mIsMoving);
   236     }
   238   protected:
   239     bool mIsMoving;
   240   };
   242   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aIsMoving));
   243 }
   245 void
   246 DOMCameraControlListener::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces)
   247 {
   248   class Callback : public DOMCallback
   249   {
   250   public:
   251     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   252              const nsTArray<ICameraControl::Face>& aFaces)
   253       : DOMCallback(aDOMCameraControl)
   254       , mFaces(aFaces)
   255     { }
   257     void
   258     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   259     {
   260       aDOMCameraControl->OnFacesDetected(mFaces);
   261     }
   263   protected:
   264     const nsTArray<ICameraControl::Face> mFaces;
   265   };
   267   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aFaces));
   268 }
   270 void
   271 DOMCameraControlListener::OnShutter()
   272 {
   273   class Callback : public DOMCallback
   274   {
   275   public:
   276     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl)
   277       : DOMCallback(aDOMCameraControl)
   278     { }
   280     void
   281     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   282     {
   283       aDOMCameraControl->OnShutter();
   284     }
   285   };
   287   NS_DispatchToMainThread(new Callback(mDOMCameraControl));
   288 }
   290 bool
   291 DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
   292 {
   293   DOM_CAMERA_LOGI("OnNewPreviewFrame: got %d x %d frame\n", aWidth, aHeight);
   295   mStream->SetCurrentFrame(gfxIntSize(aWidth, aHeight), aImage);
   296   return true;
   297 }
   299 void
   300 DOMCameraControlListener::OnAutoFocusComplete(bool aAutoFocusSucceeded)
   301 {
   302   class Callback : public DOMCallback
   303   {
   304   public:
   305     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   306              bool aAutoFocusSucceeded)
   307       : DOMCallback(aDOMCameraControl)
   308       , mAutoFocusSucceeded(aAutoFocusSucceeded)
   309     { }
   311     void
   312     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   313     {
   314       aDOMCameraControl->OnAutoFocusComplete(mAutoFocusSucceeded);
   315     }
   317   protected:
   318     bool mAutoFocusSucceeded;
   319   };
   321   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aAutoFocusSucceeded));
   322 }
   324 void
   325 DOMCameraControlListener::OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType)
   326 {
   327   class Callback : public DOMCallback
   328   {
   329   public:
   330     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   331              uint8_t* aData, uint32_t aLength, const nsAString& aMimeType)
   332       : DOMCallback(aDOMCameraControl)
   333       , mData(aData)
   334       , mLength(aLength)
   335       , mMimeType(aMimeType)
   336     { }
   338     void
   339     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   340     {
   341       nsCOMPtr<nsIDOMBlob> picture = new nsDOMMemoryFile(static_cast<void*>(mData),
   342                                                          static_cast<uint64_t>(mLength),
   343                                                          mMimeType);
   344       aDOMCameraControl->OnTakePictureComplete(picture);
   345     }
   347   protected:
   348     uint8_t* mData;
   349     uint32_t mLength;
   350     nsString mMimeType;
   351   };
   353   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aData, aLength, aMimeType));
   354 }
   356 void
   357 DOMCameraControlListener::OnError(CameraErrorContext aContext, CameraError aError)
   358 {
   359   class Callback : public DOMCallback
   360   {
   361   public:
   362     Callback(nsMainThreadPtrHandle<nsDOMCameraControl> aDOMCameraControl,
   363              CameraErrorContext aContext,
   364              CameraError aError)
   365       : DOMCallback(aDOMCameraControl)
   366       , mContext(aContext)
   367       , mError(aError)
   368     { }
   370     virtual void
   371     RunCallback(nsDOMCameraControl* aDOMCameraControl) MOZ_OVERRIDE
   372     {
   373       nsString error;
   375       switch (mError) {
   376         case kErrorServiceFailed:
   377           error = NS_LITERAL_STRING("ErrorServiceFailed");
   378           break;
   380         case kErrorSetPictureSizeFailed:
   381           error = NS_LITERAL_STRING("ErrorSetPictureSizeFailed");
   382           break;
   384         case kErrorSetThumbnailSizeFailed:
   385           error = NS_LITERAL_STRING("ErrorSetThumbnailSizeFailed");
   386           break;
   388         case kErrorApiFailed:
   389           // XXXmikeh legacy error placeholder
   390           error = NS_LITERAL_STRING("FAILURE");
   391           break;
   393         default:
   394           error = NS_LITERAL_STRING("ErrorUnknown");
   395           break;
   396       }
   397       aDOMCameraControl->OnError(mContext, error);
   398     }
   400   protected:
   401     CameraErrorContext mContext;
   402     CameraError mError;
   403   };
   405   NS_DispatchToMainThread(new Callback(mDOMCameraControl, aContext, aError));
   406 }

mercurial