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 "DOMCameraControl.h"
6 #include "base/basictypes.h"
8 #include "nsDOMClassInfo.h"
9 #include "nsHashPropertyBag.h"
11 #include "DeviceStorage.h"
12 #include "DeviceStorageFileDescriptor.h"
13 #include "mozilla/dom/TabChild.h"
14 #include "mozilla/ipc/FileDescriptorUtils.h"
15 #include "mozilla/MediaManager.h"
16 #include "mozilla/Services.h"
17 #include "mozilla/unused.h"
18 #include "nsIAppsService.h"
19 #include "nsIObserverService.h"
20 #include "nsIDOMDeviceStorage.h"
21 #include "nsIDOMEventListener.h"
22 #include "nsIScriptSecurityManager.h"
23 #include "Navigator.h"
24 #include "nsXULAppAPI.h"
25 #include "DOMCameraManager.h"
26 #include "DOMCameraCapabilities.h"
27 #include "CameraCommon.h"
28 #include "nsGlobalWindow.h"
29 #include "CameraPreviewMediaStream.h"
30 #include "mozilla/dom/CameraControlBinding.h"
31 #include "mozilla/dom/CameraManagerBinding.h"
32 #include "mozilla/dom/CameraCapabilitiesBinding.h"
33 #include "DOMCameraDetectedFace.h"
34 #include "mozilla/dom/BindingUtils.h"
35 #include "nsPrintfCString.h"
37 using namespace mozilla
;
38 using namespace mozilla::dom
;
39 using namespace mozilla::ipc
;
41 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl
)
42 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
43 NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream
)
44 // nsISupports is an ambiguous base of nsDOMCameraControl
45 // so we need to work around that.
46 if (aIID
.Equals(NS_GET_IID(nsDOMCameraControl
)))
47 foundInterface
= static_cast<nsISupports
*>(static_cast<void*>(this));
49 NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream
)
51 NS_IMPL_ADDREF_INHERITED(nsDOMCameraControl
, DOMMediaStream
)
52 NS_IMPL_RELEASE_INHERITED(nsDOMCameraControl
, DOMMediaStream
)
54 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl
, DOMMediaStream
,
58 mGetCameraOnSuccessCb
,
60 mAutoFocusOnSuccessCb
,
62 mTakePictureOnSuccessCb
,
63 mTakePictureOnErrorCb
,
64 mStartRecordingOnSuccessCb
,
65 mStartRecordingOnErrorCb
,
68 mSetConfigurationOnSuccessCb
,
69 mSetConfigurationOnErrorCb
,
72 mOnRecorderStateChangeCb
,
73 mOnPreviewStateChangeCb
,
75 mOnAutoFocusCompletedCb
,
80 nsDOMCameraControl::HasSupport(JSContext
* aCx
, JSObject
* aGlobal
)
82 return Navigator::HasCameraSupport(aCx
, aGlobal
);
85 class mozilla::StartRecordingHelper
: public nsIDOMEventListener
89 NS_DECL_NSIDOMEVENTLISTENER
91 StartRecordingHelper(nsDOMCameraControl
* aDOMCameraControl
)
92 : mDOMCameraControl(aDOMCameraControl
)
94 MOZ_COUNT_CTOR(StartRecordingHelper
);
98 virtual ~StartRecordingHelper()
100 MOZ_COUNT_DTOR(StartRecordingHelper
);
104 nsRefPtr
<nsDOMCameraControl
> mDOMCameraControl
;
108 StartRecordingHelper::HandleEvent(nsIDOMEvent
* aEvent
)
111 aEvent
->GetType(eventType
);
113 mDOMCameraControl
->OnCreatedFileDescriptor(eventType
.EqualsLiteral("success"));
117 NS_IMPL_ISUPPORTS(mozilla::StartRecordingHelper
, nsIDOMEventListener
)
119 nsDOMCameraControl::DOMCameraConfiguration::DOMCameraConfiguration()
120 : CameraConfiguration()
122 , mMaxMeteringAreas(0)
124 MOZ_COUNT_CTOR(nsDOMCameraControl::DOMCameraConfiguration
);
127 nsDOMCameraControl::DOMCameraConfiguration::DOMCameraConfiguration(const CameraConfiguration
& aConfiguration
)
128 : CameraConfiguration(aConfiguration
)
130 , mMaxMeteringAreas(0)
132 MOZ_COUNT_CTOR(nsDOMCameraControl::DOMCameraConfiguration
);
135 nsDOMCameraControl::DOMCameraConfiguration::~DOMCameraConfiguration()
137 MOZ_COUNT_DTOR(nsDOMCameraControl::DOMCameraConfiguration
);
140 nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId
,
141 const CameraConfiguration
& aInitialConfig
,
142 GetCameraCallback
* aOnSuccess
,
143 CameraErrorCallback
* aOnError
,
144 nsPIDOMWindow
* aWindow
)
146 , mCameraControl(nullptr)
147 , mAudioChannelAgent(nullptr)
148 , mGetCameraOnSuccessCb(aOnSuccess
)
149 , mGetCameraOnErrorCb(aOnError
)
150 , mAutoFocusOnSuccessCb(nullptr)
151 , mAutoFocusOnErrorCb(nullptr)
152 , mTakePictureOnSuccessCb(nullptr)
153 , mTakePictureOnErrorCb(nullptr)
154 , mStartRecordingOnSuccessCb(nullptr)
155 , mStartRecordingOnErrorCb(nullptr)
156 , mReleaseOnSuccessCb(nullptr)
157 , mReleaseOnErrorCb(nullptr)
158 , mSetConfigurationOnSuccessCb(nullptr)
159 , mSetConfigurationOnErrorCb(nullptr)
160 , mOnShutterCb(nullptr)
161 , mOnClosedCb(nullptr)
162 , mOnRecorderStateChangeCb(nullptr)
163 , mOnPreviewStateChangeCb(nullptr)
164 , mOnAutoFocusMovingCb(nullptr)
165 , mOnAutoFocusCompletedCb(nullptr)
166 , mOnFacesDetectedCb(nullptr)
169 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
170 mInput
= new CameraPreviewMediaStream(this);
174 nsRefPtr
<DOMCameraConfiguration
> initialConfig
=
175 new DOMCameraConfiguration(aInitialConfig
);
177 // Create and initialize the underlying camera.
178 ICameraControl::Configuration config
;
179 bool haveInitialConfig
= false;
182 switch (aInitialConfig
.mMode
) {
183 case CameraMode::Picture
:
184 config
.mMode
= ICameraControl::kPictureMode
;
185 haveInitialConfig
= true;
188 case CameraMode::Video
:
189 config
.mMode
= ICameraControl::kVideoMode
;
190 haveInitialConfig
= true;
193 case CameraMode::Unspecified
:
197 MOZ_ASSERT_UNREACHABLE("Unanticipated camera mode!");
201 if (haveInitialConfig
) {
202 config
.mPreviewSize
.width
= aInitialConfig
.mPreviewSize
.mWidth
;
203 config
.mPreviewSize
.height
= aInitialConfig
.mPreviewSize
.mHeight
;
204 config
.mRecorderProfile
= aInitialConfig
.mRecorderProfile
;
207 mCameraControl
= ICameraControl::Create(aCameraId
);
208 mCurrentConfiguration
= initialConfig
.forget();
210 // Attach our DOM-facing media stream to our viewfinder stream.
211 SetHintContents(HINT_CONTENTS_VIDEO
);
212 InitStreamCommon(mInput
);
213 MOZ_ASSERT(mWindow
, "Shouldn't be created with a null window!");
214 if (mWindow
->GetExtantDoc()) {
215 CombineWithPrincipal(mWindow
->GetExtantDoc()->NodePrincipal());
218 // Register a listener for camera events.
219 mListener
= new DOMCameraControlListener(this, mInput
);
220 mCameraControl
->AddListener(mListener
);
222 // Start the camera...
223 if (haveInitialConfig
) {
224 rv
= mCameraControl
->Start(&config
);
226 rv
= mCameraControl
->Start();
229 mListener
->OnUserError(DOMCameraControlListener::kInStartCamera
, rv
);
233 nsDOMCameraControl::~nsDOMCameraControl()
235 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__
, __LINE__
, this);
239 nsDOMCameraControl::WrapObject(JSContext
* aCx
)
241 return CameraControlBinding::Wrap(aCx
, this);
245 nsDOMCameraControl::IsWindowStillActive()
247 return nsDOMCameraManager::IsWindowStillActive(mWindow
->WindowID());
250 #define THROW_IF_NO_CAMERACONTROL(...) \
252 if (!mCameraControl) { \
253 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__, __LINE__); \
254 aRv = NS_ERROR_NOT_AVAILABLE; \
255 return __VA_ARGS__; \
259 // Setter for weighted regions: { top, bottom, left, right, weight }
261 nsDOMCameraControl::Set(uint32_t aKey
, const Optional
<Sequence
<CameraRegion
> >& aValue
, uint32_t aLimit
)
263 if (!mCameraControl
) {
264 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__
, __LINE__
);
265 return NS_ERROR_NOT_AVAILABLE
;
268 DOM_CAMERA_LOGI("%s:%d : aLimit = 0, nothing to do\n", __func__
, __LINE__
);
272 nsTArray
<ICameraControl::Region
> regionArray
;
273 if (aValue
.WasPassed()) {
274 const Sequence
<CameraRegion
>& regions
= aValue
.Value();
275 uint32_t length
= regions
.Length();
277 DOM_CAMERA_LOGI("%s:%d : got %d regions (limited to %d)\n", __func__
, __LINE__
, length
, aLimit
);
278 if (length
> aLimit
) {
282 // aLimit supplied by camera library provides sane ceiling (i.e. <10)
283 regionArray
.SetCapacity(length
);
285 for (uint32_t i
= 0; i
< length
; ++i
) {
286 ICameraControl::Region
* r
= regionArray
.AppendElement();
287 const CameraRegion
®ion
= regions
[i
];
288 r
->top
= region
.mTop
;
289 r
->left
= region
.mLeft
;
290 r
->bottom
= region
.mBottom
;
291 r
->right
= region
.mRight
;
292 r
->weight
= region
.mWeight
;
294 DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%u\n",
304 DOM_CAMERA_LOGI("%s:%d : clear regions\n", __func__
, __LINE__
);
306 return mCameraControl
->Set(aKey
, regionArray
);
309 // Getter for weighted regions: { top, bottom, left, right, weight }
311 nsDOMCameraControl::Get(uint32_t aKey
, nsTArray
<CameraRegion
>& aValue
)
313 if (!mCameraControl
) {
314 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__
, __LINE__
);
315 return NS_ERROR_NOT_AVAILABLE
;
318 nsTArray
<ICameraControl::Region
> regionArray
;
320 nsresult rv
= mCameraControl
->Get(aKey
, regionArray
);
321 NS_ENSURE_SUCCESS(rv
, rv
);
323 uint32_t length
= regionArray
.Length();
324 DOM_CAMERA_LOGI("%s:%d : got %d regions\n", __func__
, __LINE__
, length
);
325 aValue
.SetLength(length
);
327 for (uint32_t i
= 0; i
< length
; ++i
) {
328 ICameraControl::Region
& r
= regionArray
[i
];
329 CameraRegion
& v
= aValue
[i
];
332 v
.mBottom
= r
.bottom
;
334 v
.mWeight
= r
.weight
;
336 DOM_CAMERA_LOGI("region %d: top=%d, left=%d, bottom=%d, right=%d, weight=%u\n",
350 nsDOMCameraControl::GetEffect(nsString
& aEffect
, ErrorResult
& aRv
)
352 THROW_IF_NO_CAMERACONTROL();
353 aRv
= mCameraControl
->Get(CAMERA_PARAM_EFFECT
, aEffect
);
356 nsDOMCameraControl::SetEffect(const nsAString
& aEffect
, ErrorResult
& aRv
)
358 THROW_IF_NO_CAMERACONTROL();
359 aRv
= mCameraControl
->Set(CAMERA_PARAM_EFFECT
, aEffect
);
363 nsDOMCameraControl::GetWhiteBalanceMode(nsString
& aWhiteBalanceMode
, ErrorResult
& aRv
)
365 THROW_IF_NO_CAMERACONTROL();
366 aRv
= mCameraControl
->Get(CAMERA_PARAM_WHITEBALANCE
, aWhiteBalanceMode
);
369 nsDOMCameraControl::SetWhiteBalanceMode(const nsAString
& aWhiteBalanceMode
, ErrorResult
& aRv
)
371 THROW_IF_NO_CAMERACONTROL();
372 aRv
= mCameraControl
->Set(CAMERA_PARAM_WHITEBALANCE
, aWhiteBalanceMode
);
376 nsDOMCameraControl::GetSceneMode(nsString
& aSceneMode
, ErrorResult
& aRv
)
378 THROW_IF_NO_CAMERACONTROL();
379 aRv
= mCameraControl
->Get(CAMERA_PARAM_SCENEMODE
, aSceneMode
);
382 nsDOMCameraControl::SetSceneMode(const nsAString
& aSceneMode
, ErrorResult
& aRv
)
384 THROW_IF_NO_CAMERACONTROL();
385 aRv
= mCameraControl
->Set(CAMERA_PARAM_SCENEMODE
, aSceneMode
);
389 nsDOMCameraControl::GetFlashMode(nsString
& aFlashMode
, ErrorResult
& aRv
)
391 THROW_IF_NO_CAMERACONTROL();
392 aRv
= mCameraControl
->Get(CAMERA_PARAM_FLASHMODE
, aFlashMode
);
395 nsDOMCameraControl::SetFlashMode(const nsAString
& aFlashMode
, ErrorResult
& aRv
)
397 THROW_IF_NO_CAMERACONTROL();
398 aRv
= mCameraControl
->Set(CAMERA_PARAM_FLASHMODE
, aFlashMode
);
402 nsDOMCameraControl::GetFocusMode(nsString
& aFocusMode
, ErrorResult
& aRv
)
404 THROW_IF_NO_CAMERACONTROL();
405 aRv
= mCameraControl
->Get(CAMERA_PARAM_FOCUSMODE
, aFocusMode
);
408 nsDOMCameraControl::SetFocusMode(const nsAString
& aFocusMode
, ErrorResult
& aRv
)
410 THROW_IF_NO_CAMERACONTROL();
411 aRv
= mCameraControl
->Set(CAMERA_PARAM_FOCUSMODE
, aFocusMode
);
415 nsDOMCameraControl::GetIsoMode(nsString
& aIsoMode
, ErrorResult
& aRv
)
417 THROW_IF_NO_CAMERACONTROL();
418 aRv
= mCameraControl
->Get(CAMERA_PARAM_ISOMODE
, aIsoMode
);
421 nsDOMCameraControl::SetIsoMode(const nsAString
& aIsoMode
, ErrorResult
& aRv
)
423 THROW_IF_NO_CAMERACONTROL();
424 aRv
= mCameraControl
->Set(CAMERA_PARAM_ISOMODE
, aIsoMode
);
428 nsDOMCameraControl::GetPictureQuality(ErrorResult
& aRv
)
430 THROW_IF_NO_CAMERACONTROL(1.0);
433 aRv
= mCameraControl
->Get(CAMERA_PARAM_PICTURE_QUALITY
, quality
);
437 nsDOMCameraControl::SetPictureQuality(double aQuality
, ErrorResult
& aRv
)
439 THROW_IF_NO_CAMERACONTROL();
440 aRv
= mCameraControl
->Set(CAMERA_PARAM_PICTURE_QUALITY
, aQuality
);
444 nsDOMCameraControl::GetZoom(ErrorResult
& aRv
)
446 THROW_IF_NO_CAMERACONTROL(1.0);
449 aRv
= mCameraControl
->Get(CAMERA_PARAM_ZOOM
, zoom
);
454 nsDOMCameraControl::SetZoom(double aZoom
, ErrorResult
& aRv
)
456 THROW_IF_NO_CAMERACONTROL();
457 aRv
= mCameraControl
->Set(CAMERA_PARAM_ZOOM
, aZoom
);
461 nsDOMCameraControl::GetMeteringAreas(nsTArray
<CameraRegion
>& aAreas
, ErrorResult
& aRv
)
463 aRv
= Get(CAMERA_PARAM_METERINGAREAS
, aAreas
);
466 nsDOMCameraControl::SetMeteringAreas(const Optional
<Sequence
<CameraRegion
> >& aMeteringAreas
, ErrorResult
& aRv
)
468 aRv
= Set(CAMERA_PARAM_METERINGAREAS
, aMeteringAreas
,
469 mCurrentConfiguration
->mMaxMeteringAreas
);
473 nsDOMCameraControl::GetFocusAreas(nsTArray
<CameraRegion
>& aAreas
, ErrorResult
& aRv
)
475 aRv
= Get(CAMERA_PARAM_FOCUSAREAS
, aAreas
);
478 nsDOMCameraControl::SetFocusAreas(const Optional
<Sequence
<CameraRegion
> >& aFocusAreas
, ErrorResult
& aRv
)
480 aRv
= Set(CAMERA_PARAM_FOCUSAREAS
, aFocusAreas
,
481 mCurrentConfiguration
->mMaxFocusAreas
);
485 nsDOMCameraControl::GetPictureSize(CameraSize
& aSize
, ErrorResult
& aRv
)
487 THROW_IF_NO_CAMERACONTROL();
489 ICameraControl::Size size
;
490 aRv
= mCameraControl
->Get(CAMERA_PARAM_PICTURE_SIZE
, size
);
495 aSize
.mWidth
= size
.width
;
496 aSize
.mHeight
= size
.height
;
500 nsDOMCameraControl::SetPictureSize(const CameraSize
& aSize
, ErrorResult
& aRv
)
502 THROW_IF_NO_CAMERACONTROL();
504 ICameraControl::Size s
= { aSize
.mWidth
, aSize
.mHeight
};
505 aRv
= mCameraControl
->Set(CAMERA_PARAM_PICTURE_SIZE
, s
);
509 nsDOMCameraControl::GetThumbnailSize(CameraSize
& aSize
, ErrorResult
& aRv
)
511 THROW_IF_NO_CAMERACONTROL();
513 ICameraControl::Size size
;
514 aRv
= mCameraControl
->Get(CAMERA_PARAM_THUMBNAILSIZE
, size
);
519 aSize
.mWidth
= size
.width
;
520 aSize
.mHeight
= size
.height
;
524 nsDOMCameraControl::SetThumbnailSize(const CameraSize
& aSize
, ErrorResult
& aRv
)
526 THROW_IF_NO_CAMERACONTROL();
528 ICameraControl::Size s
= { aSize
.mWidth
, aSize
.mHeight
};
529 aRv
= mCameraControl
->Set(CAMERA_PARAM_THUMBNAILSIZE
, s
);
533 nsDOMCameraControl::GetFocalLength(ErrorResult
& aRv
)
535 THROW_IF_NO_CAMERACONTROL(0.0);
538 aRv
= mCameraControl
->Get(CAMERA_PARAM_FOCALLENGTH
, focalLength
);
543 nsDOMCameraControl::GetFocusDistanceNear(ErrorResult
& aRv
)
545 THROW_IF_NO_CAMERACONTROL(0.0);
548 aRv
= mCameraControl
->Get(CAMERA_PARAM_FOCUSDISTANCENEAR
, distance
);
553 nsDOMCameraControl::GetFocusDistanceOptimum(ErrorResult
& aRv
)
555 THROW_IF_NO_CAMERACONTROL(0.0);
558 aRv
= mCameraControl
->Get(CAMERA_PARAM_FOCUSDISTANCEOPTIMUM
, distance
);
563 nsDOMCameraControl::GetFocusDistanceFar(ErrorResult
& aRv
)
565 THROW_IF_NO_CAMERACONTROL(0.0);
568 aRv
= mCameraControl
->Get(CAMERA_PARAM_FOCUSDISTANCEFAR
, distance
);
573 nsDOMCameraControl::SetExposureCompensation(double aCompensation
, ErrorResult
& aRv
)
575 THROW_IF_NO_CAMERACONTROL();
576 aRv
= mCameraControl
->Set(CAMERA_PARAM_EXPOSURECOMPENSATION
, aCompensation
);
580 nsDOMCameraControl::GetExposureCompensation(ErrorResult
& aRv
)
582 THROW_IF_NO_CAMERACONTROL(0.0);
585 aRv
= mCameraControl
->Get(CAMERA_PARAM_EXPOSURECOMPENSATION
, compensation
);
590 nsDOMCameraControl::SensorAngle()
593 if (mCameraControl
) {
594 mCameraControl
->Get(CAMERA_PARAM_SENSORANGLE
, angle
);
599 // Callback attributes
601 CameraShutterCallback
*
602 nsDOMCameraControl::GetOnShutter()
607 nsDOMCameraControl::SetOnShutter(CameraShutterCallback
* aCb
)
612 CameraClosedCallback
*
613 nsDOMCameraControl::GetOnClosed()
618 nsDOMCameraControl::SetOnClosed(CameraClosedCallback
* aCb
)
623 CameraRecorderStateChange
*
624 nsDOMCameraControl::GetOnRecorderStateChange()
626 return mOnRecorderStateChangeCb
;
629 nsDOMCameraControl::SetOnRecorderStateChange(CameraRecorderStateChange
* aCb
)
631 mOnRecorderStateChangeCb
= aCb
;
634 CameraPreviewStateChange
*
635 nsDOMCameraControl::GetOnPreviewStateChange()
637 return mOnPreviewStateChangeCb
;
640 nsDOMCameraControl::SetOnPreviewStateChange(CameraPreviewStateChange
* aCb
)
642 mOnPreviewStateChangeCb
= aCb
;
645 CameraAutoFocusMovingCallback
*
646 nsDOMCameraControl::GetOnAutoFocusMoving()
648 return mOnAutoFocusMovingCb
;
651 nsDOMCameraControl::SetOnAutoFocusMoving(CameraAutoFocusMovingCallback
* aCb
)
653 mOnAutoFocusMovingCb
= aCb
;
656 CameraAutoFocusCallback
*
657 nsDOMCameraControl::GetOnAutoFocusCompleted()
659 return mOnAutoFocusCompletedCb
;
662 nsDOMCameraControl::SetOnAutoFocusCompleted(CameraAutoFocusCallback
* aCb
)
664 mOnAutoFocusCompletedCb
= aCb
;
667 CameraFaceDetectionCallback
*
668 nsDOMCameraControl::GetOnFacesDetected()
670 return mOnFacesDetectedCb
;
673 nsDOMCameraControl::SetOnFacesDetected(CameraFaceDetectionCallback
* aCb
)
675 mOnFacesDetectedCb
= aCb
;
678 already_AddRefed
<dom::CameraCapabilities
>
679 nsDOMCameraControl::Capabilities()
681 nsRefPtr
<CameraCapabilities
> caps
= mCapabilities
;
684 caps
= new CameraCapabilities(mWindow
);
685 nsresult rv
= caps
->Populate(mCameraControl
);
687 DOM_CAMERA_LOGW("Failed to populate camera capabilities (%d)\n", rv
);
690 mCapabilities
= caps
;
693 return caps
.forget();
698 nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions
& aOptions
,
699 nsDOMDeviceStorage
& aStorageArea
,
700 const nsAString
& aFilename
,
701 CameraStartRecordingCallback
& aOnSuccess
,
702 const Optional
<OwningNonNull
<CameraErrorCallback
> >& aOnError
,
705 NotifyRecordingStatusChange(NS_LITERAL_STRING("starting"));
708 if (!mAudioChannelAgent
) {
709 mAudioChannelAgent
= do_CreateInstance("@mozilla.org/audiochannelagent;1");
710 if (mAudioChannelAgent
) {
711 // Camera app will stop recording when it falls to the background, so no callback is necessary.
712 mAudioChannelAgent
->Init(mWindow
, (int32_t)AudioChannel::Content
, nullptr);
713 // Video recording doesn't output any sound, so it's not necessary to check canPlay.
715 mAudioChannelAgent
->StartPlaying(&canPlay
);
720 nsCOMPtr
<nsIDOMDOMRequest
> request
;
721 mDSFileDescriptor
= new DeviceStorageFileDescriptor();
722 aRv
= aStorageArea
.CreateFileDescriptor(aFilename
, mDSFileDescriptor
.get(),
723 getter_AddRefs(request
));
729 mStartRecordingOnSuccessCb
= &aOnSuccess
;
730 mStartRecordingOnErrorCb
= nullptr;
731 if (aOnError
.WasPassed()) {
732 mStartRecordingOnErrorCb
= &aOnError
.Value();
735 nsCOMPtr
<nsIDOMEventListener
> listener
= new StartRecordingHelper(this);
736 request
->AddEventListener(NS_LITERAL_STRING("success"), listener
, false);
737 request
->AddEventListener(NS_LITERAL_STRING("error"), listener
, false);
741 nsDOMCameraControl::OnCreatedFileDescriptor(bool aSucceeded
)
743 nsresult rv
= NS_ERROR_FAILURE
;
744 if (!mCameraControl
) {
745 rv
= NS_ERROR_NOT_INITIALIZED
;
746 } else if (aSucceeded
&& mDSFileDescriptor
->mFileDescriptor
.IsValid()) {
747 ICameraControl::StartRecordingOptions o
;
749 o
.rotation
= mOptions
.mRotation
;
750 o
.maxFileSizeBytes
= mOptions
.mMaxFileSizeBytes
;
751 o
.maxVideoLengthMs
= mOptions
.mMaxVideoLengthMs
;
752 o
.autoEnableLowLightTorch
= mOptions
.mAutoEnableLowLightTorch
;
753 rv
= mCameraControl
->StartRecording(mDSFileDescriptor
.get(), &o
);
754 if (NS_SUCCEEDED(rv
)) {
759 OnUserError(CameraControlListener::kInStartRecording
, rv
);
761 if (mDSFileDescriptor
->mFileDescriptor
.IsValid()) {
762 // An error occured. We need to manually close the file associated with the
763 // FileDescriptor, and we shouldn't do this on the main thread, so we
764 // use a little helper.
765 nsRefPtr
<CloseFileRunnable
> closer
=
766 new CloseFileRunnable(mDSFileDescriptor
->mFileDescriptor
);
772 nsDOMCameraControl::StopRecording(ErrorResult
& aRv
)
774 THROW_IF_NO_CAMERACONTROL();
777 if (mAudioChannelAgent
) {
778 mAudioChannelAgent
->StopPlaying();
779 mAudioChannelAgent
= nullptr;
783 aRv
= mCameraControl
->StopRecording();
787 nsDOMCameraControl::ResumePreview(ErrorResult
& aRv
)
789 THROW_IF_NO_CAMERACONTROL();
790 aRv
= mCameraControl
->StartPreview();
793 class ImmediateErrorCallback
: public nsRunnable
796 ImmediateErrorCallback(CameraErrorCallback
* aCallback
, const nsAString
& aMessage
)
797 : mCallback(aCallback
)
804 MOZ_ASSERT(NS_IsMainThread());
806 mCallback
->Call(mMessage
, ignored
);
811 nsRefPtr
<CameraErrorCallback
> mCallback
;
816 nsDOMCameraControl::SetConfiguration(const CameraConfiguration
& aConfiguration
,
817 const Optional
<OwningNonNull
<CameraSetConfigurationCallback
> >& aOnSuccess
,
818 const Optional
<OwningNonNull
<CameraErrorCallback
> >& aOnError
,
821 if (!mCameraControl
) {
822 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__
, __LINE__
);
823 if (aOnError
.WasPassed()) {
824 NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError
.Value(),
825 NS_LITERAL_STRING("HardwareClosed")));
827 // Only throw if we don't have an error callback.
828 aRv
= NS_ERROR_NOT_AVAILABLE
;
833 nsRefPtr
<CameraTakePictureCallback
> cb
= mTakePictureOnSuccessCb
;
835 // We're busy taking a picture, can't change modes right now.
836 if (aOnError
.WasPassed()) {
837 // There is already a call to TakePicture() in progress, abort this
838 // call and invoke the error callback (if one was passed in).
839 NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError
.Value(),
840 NS_LITERAL_STRING("TakePictureInProgress")));
842 // Only throw if no error callback was passed in.
843 aRv
= NS_ERROR_FAILURE
;
848 ICameraControl::Configuration config
;
849 config
.mRecorderProfile
= aConfiguration
.mRecorderProfile
;
850 config
.mPreviewSize
.width
= aConfiguration
.mPreviewSize
.mWidth
;
851 config
.mPreviewSize
.height
= aConfiguration
.mPreviewSize
.mHeight
;
852 config
.mMode
= ICameraControl::kPictureMode
;
853 if (aConfiguration
.mMode
== CameraMode::Video
) {
854 config
.mMode
= ICameraControl::kVideoMode
;
857 mSetConfigurationOnSuccessCb
= nullptr;
858 if (aOnSuccess
.WasPassed()) {
859 mSetConfigurationOnSuccessCb
= &aOnSuccess
.Value();
861 mSetConfigurationOnErrorCb
= nullptr;
862 if (aOnError
.WasPassed()) {
863 mSetConfigurationOnErrorCb
= &aOnError
.Value();
866 aRv
= mCameraControl
->SetConfiguration(config
);
870 nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback
& aOnSuccess
,
871 const Optional
<OwningNonNull
<CameraErrorCallback
> >& aOnError
,
874 if (!mCameraControl
) {
875 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__
, __LINE__
);
876 if (aOnError
.WasPassed()) {
877 NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError
.Value(),
878 NS_LITERAL_STRING("HardwareClosed")));
880 // Only throw if we don't have an error callback.
881 aRv
= NS_ERROR_NOT_AVAILABLE
;
886 nsRefPtr
<CameraErrorCallback
> ecb
= mAutoFocusOnErrorCb
.forget();
888 // There is already a call to AutoFocus() in progress, cancel it and
889 // invoke the error callback (if one was passed in).
890 NS_DispatchToMainThread(new ImmediateErrorCallback(ecb
,
891 NS_LITERAL_STRING("AutoFocusInterrupted")));
894 mAutoFocusOnSuccessCb
= &aOnSuccess
;
895 mAutoFocusOnErrorCb
= nullptr;
896 if (aOnError
.WasPassed()) {
897 mAutoFocusOnErrorCb
= &aOnError
.Value();
900 aRv
= mCameraControl
->AutoFocus();
904 nsDOMCameraControl::StartFaceDetection(ErrorResult
& aRv
)
906 THROW_IF_NO_CAMERACONTROL();
907 aRv
= mCameraControl
->StartFaceDetection();
911 nsDOMCameraControl::StopFaceDetection(ErrorResult
& aRv
)
913 THROW_IF_NO_CAMERACONTROL();
914 aRv
= mCameraControl
->StopFaceDetection();
918 nsDOMCameraControl::TakePicture(const CameraPictureOptions
& aOptions
,
919 CameraTakePictureCallback
& aOnSuccess
,
920 const Optional
<OwningNonNull
<CameraErrorCallback
> >& aOnError
,
923 if (!mCameraControl
) {
924 DOM_CAMERA_LOGW("mCameraControl is null at %s:%d\n", __func__
, __LINE__
);
925 if (aOnError
.WasPassed()) {
926 NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError
.Value(),
927 NS_LITERAL_STRING("HardwareClosed")));
929 // Only throw if we don't have an error callback.
930 aRv
= NS_ERROR_NOT_AVAILABLE
;
935 nsRefPtr
<CameraTakePictureCallback
> cb
= mTakePictureOnSuccessCb
;
937 if (aOnError
.WasPassed()) {
938 // There is already a call to TakePicture() in progress, abort this new
939 // one and invoke the error callback (if one was passed in).
940 NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError
.Value(),
941 NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
943 // Only throw if no error callback was passed in.
944 aRv
= NS_ERROR_FAILURE
;
950 ICameraControlParameterSetAutoEnter
batch(mCameraControl
);
952 // XXXmikeh - remove this: see bug 931155
953 ICameraControl::Size s
;
954 s
.width
= aOptions
.mPictureSize
.mWidth
;
955 s
.height
= aOptions
.mPictureSize
.mHeight
;
957 ICameraControl::Position p
;
958 p
.latitude
= aOptions
.mPosition
.mLatitude
;
959 p
.longitude
= aOptions
.mPosition
.mLongitude
;
960 p
.altitude
= aOptions
.mPosition
.mAltitude
;
961 p
.timestamp
= aOptions
.mPosition
.mTimestamp
;
963 if (s
.width
&& s
.height
) {
964 mCameraControl
->Set(CAMERA_PARAM_PICTURE_SIZE
, s
);
966 mCameraControl
->Set(CAMERA_PARAM_PICTURE_ROTATION
, aOptions
.mRotation
);
967 mCameraControl
->Set(CAMERA_PARAM_PICTURE_FILEFORMAT
, aOptions
.mFileFormat
);
968 mCameraControl
->Set(CAMERA_PARAM_PICTURE_DATETIME
, aOptions
.mDateTime
);
969 mCameraControl
->SetLocation(p
);
972 mTakePictureOnSuccessCb
= &aOnSuccess
;
973 mTakePictureOnErrorCb
= nullptr;
974 if (aOnError
.WasPassed()) {
975 mTakePictureOnErrorCb
= &aOnError
.Value();
978 aRv
= mCameraControl
->TakePicture();
982 nsDOMCameraControl::ReleaseHardware(const Optional
<OwningNonNull
<CameraReleaseCallback
> >& aOnSuccess
,
983 const Optional
<OwningNonNull
<CameraErrorCallback
> >& aOnError
,
986 if (!mCameraControl
) {
987 // Always succeed if the camera instance is already closed.
988 if (aOnSuccess
.WasPassed()) {
989 class Message
: public nsRunnable
992 Message(CameraReleaseCallback
* aOnSuccess
)
993 : mOnSuccess(aOnSuccess
)
1000 ErrorResult ignored
;
1001 mOnSuccess
->Call(ignored
);
1007 nsRefPtr
<CameraReleaseCallback
> mOnSuccess
;
1010 NS_DispatchToMainThread(new Message(&aOnSuccess
.Value()));
1015 mReleaseOnSuccessCb
= nullptr;
1016 if (aOnSuccess
.WasPassed()) {
1017 mReleaseOnSuccessCb
= &aOnSuccess
.Value();
1019 mReleaseOnErrorCb
= nullptr;
1020 if (aOnError
.WasPassed()) {
1021 mReleaseOnErrorCb
= &aOnError
.Value();
1024 aRv
= mCameraControl
->Stop();
1029 // Once we stop the camera, there's nothing we can do with it,
1030 // so we can throw away this reference. (This won't prevent us
1031 // from receiving the last underlying events.)
1032 mCameraControl
= nullptr;
1036 nsDOMCameraControl::ResumeContinuousFocus(ErrorResult
& aRv
)
1038 THROW_IF_NO_CAMERACONTROL();
1039 aRv
= mCameraControl
->ResumeContinuousFocus();
1043 nsDOMCameraControl::Shutdown()
1045 DOM_CAMERA_LOGI("%s:%d\n", __func__
, __LINE__
);
1047 // Remove any pending solicited event handlers; these
1048 // reference our window object, which in turn references
1049 // us. If we don't remove them, we can leak DOM objects.
1050 mGetCameraOnSuccessCb
= nullptr;
1051 mGetCameraOnErrorCb
= nullptr;
1052 mAutoFocusOnSuccessCb
= nullptr;
1053 mAutoFocusOnErrorCb
= nullptr;
1054 mTakePictureOnSuccessCb
= nullptr;
1055 mTakePictureOnErrorCb
= nullptr;
1056 mStartRecordingOnSuccessCb
= nullptr;
1057 mStartRecordingOnErrorCb
= nullptr;
1058 mReleaseOnSuccessCb
= nullptr;
1059 mReleaseOnErrorCb
= nullptr;
1060 mSetConfigurationOnSuccessCb
= nullptr;
1061 mSetConfigurationOnErrorCb
= nullptr;
1063 // Remove all of the unsolicited event handlers too.
1064 mOnShutterCb
= nullptr;
1065 mOnClosedCb
= nullptr;
1066 mOnRecorderStateChangeCb
= nullptr;
1067 mOnPreviewStateChangeCb
= nullptr;
1068 mOnAutoFocusMovingCb
= nullptr;
1069 mOnAutoFocusCompletedCb
= nullptr;
1070 mOnFacesDetectedCb
= nullptr;
1072 if (mCameraControl
) {
1073 mCameraControl
->Stop();
1074 mCameraControl
= nullptr;
1079 nsDOMCameraControl::NotifyRecordingStatusChange(const nsString
& aMsg
)
1081 NS_ENSURE_TRUE(mWindow
, NS_ERROR_FAILURE
);
1083 return MediaManager::NotifyRecordingStatusChange(mWindow
,
1085 true /* aIsAudio */,
1086 true /* aIsVideo */);
1089 // Camera Control event handlers--must only be called from the Main Thread!
1091 nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState aState
)
1093 MOZ_ASSERT(NS_IsMainThread());
1094 ErrorResult ignored
;
1096 DOM_CAMERA_LOGI("DOM OnHardwareStateChange(%d)\n", aState
);
1099 case CameraControlListener::kHardwareOpen
:
1100 // The hardware is open, so we can return a camera to JS, even if
1101 // the preview hasn't started yet.
1102 if (mGetCameraOnSuccessCb
) {
1103 nsRefPtr
<GetCameraCallback
> cb
= mGetCameraOnSuccessCb
.forget();
1104 ErrorResult ignored
;
1105 mGetCameraOnErrorCb
= nullptr;
1106 cb
->Call(*this, *mCurrentConfiguration
, ignored
);
1110 case CameraControlListener::kHardwareClosed
:
1111 if (mReleaseOnSuccessCb
) {
1112 // If we have this event handler, this was a solicited hardware close.
1113 nsRefPtr
<CameraReleaseCallback
> cb
= mReleaseOnSuccessCb
.forget();
1114 mReleaseOnErrorCb
= nullptr;
1116 } else if(mOnClosedCb
) {
1117 // If not, something else closed the hardware.
1118 nsRefPtr
<CameraClosedCallback
> cb
= mOnClosedCb
;
1124 MOZ_ASSERT_UNREACHABLE("Unanticipated camera hardware state");
1129 nsDOMCameraControl::OnShutter()
1131 MOZ_ASSERT(NS_IsMainThread());
1133 DOM_CAMERA_LOGI("DOM ** SNAP **\n");
1135 nsRefPtr
<CameraShutterCallback
> cb
= mOnShutterCb
;
1137 ErrorResult ignored
;
1143 nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aState
)
1145 MOZ_ASSERT(NS_IsMainThread());
1147 if (!mOnPreviewStateChangeCb
) {
1153 case CameraControlListener::kPreviewStarted
:
1154 state
= NS_LITERAL_STRING("started");
1158 state
= NS_LITERAL_STRING("stopped");
1162 nsRefPtr
<CameraPreviewStateChange
> cb
= mOnPreviewStateChangeCb
;
1163 ErrorResult ignored
;
1164 cb
->Call(state
, ignored
);
1168 nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState aState
,
1169 int32_t aArg
, int32_t aTrackNum
)
1171 // For now, we do nothing with 'aStatus' and 'aTrackNum'.
1172 MOZ_ASSERT(NS_IsMainThread());
1174 ErrorResult ignored
;
1178 case CameraControlListener::kRecorderStarted
:
1179 if (mStartRecordingOnSuccessCb
) {
1180 nsRefPtr
<CameraStartRecordingCallback
> cb
= mStartRecordingOnSuccessCb
.forget();
1181 mStartRecordingOnErrorCb
= nullptr;
1184 state
= NS_LITERAL_STRING("Started");
1187 case CameraControlListener::kRecorderStopped
:
1188 NotifyRecordingStatusChange(NS_LITERAL_STRING("shutdown"));
1189 state
= NS_LITERAL_STRING("Stopped");
1192 #ifdef MOZ_B2G_CAMERA
1193 case CameraControlListener::kFileSizeLimitReached
:
1194 state
= NS_LITERAL_STRING("FileSizeLimitReached");
1197 case CameraControlListener::kVideoLengthLimitReached
:
1198 state
= NS_LITERAL_STRING("VideoLengthLimitReached");
1201 case CameraControlListener::kTrackCompleted
:
1202 state
= NS_LITERAL_STRING("TrackCompleted");
1205 case CameraControlListener::kTrackFailed
:
1206 state
= NS_LITERAL_STRING("TrackFailed");
1209 case CameraControlListener::kMediaRecorderFailed
:
1210 state
= NS_LITERAL_STRING("MediaRecorderFailed");
1213 case CameraControlListener::kMediaServerFailed
:
1214 state
= NS_LITERAL_STRING("MediaServerFailed");
1219 MOZ_ASSERT_UNREACHABLE("Unanticipated video recorder error");
1223 nsRefPtr
<CameraRecorderStateChange
> cb
= mOnRecorderStateChangeCb
;
1225 cb
->Call(state
, ignored
);
1230 nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration
* aConfiguration
)
1232 MOZ_ASSERT(NS_IsMainThread());
1234 // Update our record of the current camera configuration
1235 mCurrentConfiguration
= aConfiguration
;
1237 DOM_CAMERA_LOGI("DOM OnConfigurationChange: this=%p\n", this);
1238 DOM_CAMERA_LOGI(" mode : %s\n",
1239 mCurrentConfiguration
->mMode
== CameraMode::Video
? "video" : "picture");
1240 DOM_CAMERA_LOGI(" maximum focus areas : %d\n",
1241 mCurrentConfiguration
->mMaxFocusAreas
);
1242 DOM_CAMERA_LOGI(" maximum metering areas : %d\n",
1243 mCurrentConfiguration
->mMaxMeteringAreas
);
1244 DOM_CAMERA_LOGI(" preview size (w x h) : %d x %d\n",
1245 mCurrentConfiguration
->mPreviewSize
.mWidth
, mCurrentConfiguration
->mPreviewSize
.mHeight
);
1246 DOM_CAMERA_LOGI(" recorder profile : %s\n",
1247 NS_ConvertUTF16toUTF8(mCurrentConfiguration
->mRecorderProfile
).get());
1249 nsRefPtr
<CameraSetConfigurationCallback
> cb
= mSetConfigurationOnSuccessCb
.forget();
1250 mSetConfigurationOnErrorCb
= nullptr;
1252 ErrorResult ignored
;
1253 cb
->Call(*mCurrentConfiguration
, ignored
);
1258 nsDOMCameraControl::OnAutoFocusComplete(bool aAutoFocusSucceeded
)
1260 MOZ_ASSERT(NS_IsMainThread());
1262 nsRefPtr
<CameraAutoFocusCallback
> cb
= mAutoFocusOnSuccessCb
.forget();
1263 mAutoFocusOnErrorCb
= nullptr;
1265 ErrorResult ignored
;
1266 cb
->Call(aAutoFocusSucceeded
, ignored
);
1269 cb
= mOnAutoFocusCompletedCb
;
1271 ErrorResult ignored
;
1272 cb
->Call(aAutoFocusSucceeded
, ignored
);
1277 nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving
)
1279 MOZ_ASSERT(NS_IsMainThread());
1281 nsRefPtr
<CameraAutoFocusMovingCallback
> cb
= mOnAutoFocusMovingCb
;
1283 ErrorResult ignored
;
1284 cb
->Call(aIsMoving
, ignored
);
1289 nsDOMCameraControl::OnFacesDetected(const nsTArray
<ICameraControl::Face
>& aFaces
)
1291 DOM_CAMERA_LOGI("DOM OnFacesDetected %u face(s)\n", aFaces
.Length());
1292 MOZ_ASSERT(NS_IsMainThread());
1294 nsRefPtr
<CameraFaceDetectionCallback
> cb
= mOnFacesDetectedCb
;
1299 Sequence
<OwningNonNull
<DOMCameraDetectedFace
> > faces
;
1300 uint32_t len
= aFaces
.Length();
1302 if (faces
.SetCapacity(len
)) {
1303 nsRefPtr
<DOMCameraDetectedFace
> f
;
1304 for (uint32_t i
= 0; i
< len
; ++i
) {
1305 f
= new DOMCameraDetectedFace(static_cast<DOMMediaStream
*>(this), aFaces
[i
]);
1306 *faces
.AppendElement() = f
.forget().take();
1310 ErrorResult ignored
;
1311 cb
->Call(faces
, ignored
);
1315 nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob
* aPicture
)
1317 MOZ_ASSERT(NS_IsMainThread());
1319 nsRefPtr
<CameraTakePictureCallback
> cb
= mTakePictureOnSuccessCb
.forget();
1320 mTakePictureOnErrorCb
= nullptr;
1322 // Warn because it shouldn't be possible to get here without
1323 // having passed a success callback into takePicture(), even
1324 // though we guard against a nullptr dereference.
1325 NS_WARNING("DOM Null success callback in OnTakePictureComplete()");
1329 ErrorResult ignored
;
1330 cb
->Call(aPicture
, ignored
);
1334 nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext
, nsresult aError
)
1336 MOZ_ASSERT(NS_IsMainThread());
1338 nsRefPtr
<CameraErrorCallback
> errorCb
;
1341 case CameraControlListener::kInStartCamera
:
1342 mGetCameraOnSuccessCb
= nullptr;
1343 errorCb
= mGetCameraOnErrorCb
.forget();
1346 case CameraControlListener::kInStopCamera
:
1347 mReleaseOnSuccessCb
= nullptr;
1348 errorCb
= mReleaseOnErrorCb
.forget();
1351 case CameraControlListener::kInSetConfiguration
:
1352 mSetConfigurationOnSuccessCb
= nullptr;
1353 errorCb
= mSetConfigurationOnErrorCb
.forget();
1356 case CameraControlListener::kInAutoFocus
:
1357 mAutoFocusOnSuccessCb
= nullptr;
1358 errorCb
= mAutoFocusOnErrorCb
.forget();
1361 case CameraControlListener::kInTakePicture
:
1362 mTakePictureOnSuccessCb
= nullptr;
1363 errorCb
= mTakePictureOnErrorCb
.forget();
1366 case CameraControlListener::kInStartRecording
:
1367 mStartRecordingOnSuccessCb
= nullptr;
1368 errorCb
= mStartRecordingOnErrorCb
.forget();
1371 case CameraControlListener::kInStartFaceDetection
:
1372 // This method doesn't have any callbacks, so all we can do is log the
1373 // failure. This only happens after the hardware has been released.
1374 NS_WARNING("Failed to start face detection");
1377 case CameraControlListener::kInStopFaceDetection
:
1378 // This method doesn't have any callbacks, so all we can do is log the
1379 // failure. This only happens after the hardware has been released.
1380 NS_WARNING("Failed to stop face detection");
1383 case CameraControlListener::kInResumeContinuousFocus
:
1384 // This method doesn't have any callbacks, so all we can do is log the
1385 // failure. This only happens after the hardware has been released.
1386 NS_WARNING("Failed to resume continuous focus");
1389 case CameraControlListener::kInStopRecording
:
1390 // This method doesn't have any callbacks, so all we can do is log the
1391 // failure. This only happens after the hardware has been released.
1392 NS_WARNING("Failed to stop recording");
1395 case CameraControlListener::kInStartPreview
:
1396 // This method doesn't have any callbacks, so all we can do is log the
1397 // failure. This only happens after the hardware has been released.
1398 NS_WARNING("Failed to (re)start preview");
1401 case CameraControlListener::kInStopPreview
:
1402 // This method doesn't have any callbacks, so all we can do is log the
1403 // failure. This only happens after the hardware has been released.
1404 NS_WARNING("Failed to stop preview");
1407 case CameraControlListener::kInSetPictureSize
:
1408 // This method doesn't have any callbacks, so all we can do is log the
1409 // failure. This only happens after the hardware has been released.
1410 NS_WARNING("Failed to set picture size");
1413 case CameraControlListener::kInSetThumbnailSize
:
1414 // This method doesn't have any callbacks, so all we can do is log the
1415 // failure. This only happens after the hardware has been released.
1416 NS_WARNING("Failed to set thumbnail size");
1421 nsPrintfCString
msg("Unhandled aContext=%u, aError=0x%x\n", aContext
, aError
);
1422 NS_WARNING(msg
.get());
1424 MOZ_ASSERT_UNREACHABLE("Unhandled user error");
1429 DOM_CAMERA_LOGW("DOM No error handler for aError=0x%x in aContext=%u\n",
1436 case NS_ERROR_INVALID_ARG
:
1437 error
= NS_LITERAL_STRING("InvalidArgument");
1440 case NS_ERROR_NOT_AVAILABLE
:
1441 error
= NS_LITERAL_STRING("NotAvailable");
1444 case NS_ERROR_NOT_IMPLEMENTED
:
1445 error
= NS_LITERAL_STRING("NotImplemented");
1448 case NS_ERROR_NOT_INITIALIZED
:
1449 error
= NS_LITERAL_STRING("HardwareClosed");
1452 case NS_ERROR_ALREADY_INITIALIZED
:
1453 error
= NS_LITERAL_STRING("HardwareAlreadyOpen");
1456 case NS_ERROR_OUT_OF_MEMORY
:
1457 error
= NS_LITERAL_STRING("OutOfMemory");
1462 nsPrintfCString
msg("Reporting aError=0x%x as generic\n", aError
);
1463 NS_WARNING(msg
.get());
1467 case NS_ERROR_FAILURE
:
1468 error
= NS_LITERAL_STRING("GeneralFailure");
1472 DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, error='%s'\n", aContext
,
1473 NS_ConvertUTF16toUTF8(error
).get());
1474 ErrorResult ignored
;
1475 errorCb
->Call(error
, ignored
);