Bug 827503 - use nsMainThreadPtrHolders when passing XPCWrappedJSes around off main thread, r=bholley,jst a=blocking-basecamp+

This commit is contained in:
Mike Habicher 2013-01-09 00:43:50 +01:00
parent d50bc07067
commit 7ff92d8901
3 changed files with 117 additions and 135 deletions

View File

@ -196,7 +196,7 @@ CameraControlImpl::Get(JSContext* aCx, uint32_t aKey, JS::Value* aValue)
nsresult
CameraControlImpl::Set(nsICameraShutterCallback* aOnShutter)
{
mOnShutterCb = aOnShutter;
mOnShutterCb = new nsMainThreadPtrHolder<nsICameraShutterCallback>(aOnShutter);
return NS_OK;
}
@ -210,7 +210,7 @@ CameraControlImpl::Get(nsICameraShutterCallback** aOnShutter)
nsresult
CameraControlImpl::Set(nsICameraClosedCallback* aOnClosed)
{
mOnClosedCb = aOnClosed;
mOnClosedCb = new nsMainThreadPtrHolder<nsICameraClosedCallback>(aOnClosed);
return NS_OK;
}
@ -224,7 +224,7 @@ CameraControlImpl::Get(nsICameraClosedCallback** aOnClosed)
nsresult
CameraControlImpl::Set(nsICameraRecorderStateChange* aOnRecorderStateChange)
{
mOnRecorderStateChangeCb = aOnRecorderStateChange;
mOnRecorderStateChangeCb = new nsMainThreadPtrHolder<nsICameraRecorderStateChange>(aOnRecorderStateChange);
return NS_OK;
}
@ -258,7 +258,7 @@ void
CameraControlImpl::OnShutterInternal()
{
DOM_CAMERA_LOGI("** SNAP **\n");
if (mOnShutterCb) {
if (mOnShutterCb.get()) {
mOnShutterCb->HandleEvent();
}
}
@ -277,7 +277,7 @@ void
CameraControlImpl::OnClosedInternal()
{
DOM_CAMERA_LOGI("Camera hardware was closed\n");
if (mOnClosedCb) {
if (mOnClosedCb.get()) {
mOnClosedCb->HandleEvent();
}
}
@ -314,14 +314,42 @@ CameraControlImpl::GetPreviewStream(CameraSize aSize, nsICameraPreviewStreamCall
nsresult
CameraControlImpl::AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError)
{
nsCOMPtr<nsIRunnable> autoFocusTask = new AutoFocusTask(this, onSuccess, onError);
MOZ_ASSERT(NS_IsMainThread());
bool cancel = false;
nsCOMPtr<nsICameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb.get();
if (cb) {
/**
* We already have a callback, so someone has already
* called autoFocus() -- cancel it.
*/
mAutoFocusOnSuccessCb = nullptr;
mAutoFocusOnErrorCb = nullptr;
cancel = true;
}
nsCOMPtr<nsIRunnable> autoFocusTask = new AutoFocusTask(this, cancel, onSuccess, onError);
return mCameraThread->Dispatch(autoFocusTask, NS_DISPATCH_NORMAL);
}
nsresult
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
{
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, aSize, aRotation, aFileFormat, aPosition, onSuccess, onError);
MOZ_ASSERT(NS_IsMainThread());
bool cancel = false;
nsCOMPtr<nsICameraTakePictureCallback> cb = mTakePictureOnSuccessCb.get();
if (cb) {
/**
* We already have a callback, so someone has already
* called takePicture() -- cancel it.
*/
mTakePictureOnSuccessCb = nullptr;
mTakePictureOnErrorCb = nullptr;
cancel = true;
}
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, cancel, aSize, aRotation, aFileFormat, aPosition, onSuccess, onError);
return mCameraThread->Dispatch(takePictureTask, NS_DISPATCH_NORMAL);
}
@ -390,9 +418,10 @@ GetPreviewStreamResult::Run()
*/
MOZ_ASSERT(NS_IsMainThread());
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
nsCOMPtr<nsICameraPreviewStreamCallback> onSuccess = mOnSuccessCb.get();
if (onSuccess && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
nsCOMPtr<nsIDOMMediaStream> stream = new DOMCameraPreview(mCameraControl, mWidth, mHeight, mFramesPerSecond);
mOnSuccessCb->HandleEvent(stream);
onSuccess->HandleEvent(stream);
}
return NS_OK;
}

View File

@ -5,8 +5,8 @@
#ifndef DOM_CAMERA_CAMERACONTROLIMPL_H
#define DOM_CAMERA_CAMERACONTROLIMPL_H
#include "nsCOMPtr.h"
#include "nsDOMFile.h"
#include "nsProxyRelease.h"
#include "DictionaryHelpers.h"
#include "nsIDOMDeviceStorage.h"
#include "DOMCameraManager.h"
@ -16,7 +16,6 @@
namespace mozilla {
class GetPreviewStreamTask;
class StartPreviewTask;
class StopPreviewTask;
@ -143,13 +142,13 @@ protected:
*/
DOMCameraPreview* mDOMPreview;
nsCOMPtr<nsICameraAutoFocusCallback> mAutoFocusOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mAutoFocusOnErrorCb;
nsCOMPtr<nsICameraTakePictureCallback> mTakePictureOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mTakePictureOnErrorCb;
nsCOMPtr<nsICameraShutterCallback> mOnShutterCb;
nsCOMPtr<nsICameraClosedCallback> mOnClosedCb;
nsCOMPtr<nsICameraRecorderStateChange> mOnRecorderStateChangeCb;
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mAutoFocusOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mAutoFocusOnErrorCb;
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mTakePictureOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mTakePictureOnErrorCb;
nsMainThreadPtrHandle<nsICameraShutterCallback> mOnShutterCb;
nsMainThreadPtrHandle<nsICameraClosedCallback> mOnClosedCb;
nsMainThreadPtrHandle<nsICameraRecorderStateChange> mOnRecorderStateChangeCb;
private:
CameraControlImpl(const CameraControlImpl&) MOZ_DELETE;
@ -160,7 +159,7 @@ private:
class CameraErrorResult : public nsRunnable
{
public:
CameraErrorResult(nsICameraErrorCallback* onError, const nsString& aErrorMsg, uint64_t aWindowId)
CameraErrorResult(nsMainThreadPtrHandle<nsICameraErrorCallback> onError, const nsString& aErrorMsg, uint64_t aWindowId)
: mOnErrorCb(onError)
, mErrorMsg(aErrorMsg)
, mWindowId(aWindowId)
@ -170,14 +169,14 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnErrorCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
if (mOnErrorCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
mOnErrorCb->HandleEvent(mErrorMsg);
}
return NS_OK;
}
protected:
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
const nsString mErrorMsg;
uint64_t mWindowId;
};
@ -186,7 +185,7 @@ protected:
class GetPreviewStreamResult : public nsRunnable
{
public:
GetPreviewStreamResult(CameraControlImpl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond, nsICameraPreviewStreamCallback* onSuccess, uint64_t aWindowId)
GetPreviewStreamResult(CameraControlImpl* aCameraControl, uint32_t aWidth, uint32_t aHeight, uint32_t aFramesPerSecond, nsMainThreadPtrHandle<nsICameraPreviewStreamCallback>& onSuccess, uint64_t aWindowId)
: mCameraControl(aCameraControl)
, mWidth(aWidth)
, mHeight(aHeight)
@ -210,7 +209,7 @@ protected:
uint32_t mWidth;
uint32_t mHeight;
uint32_t mFramesPerSecond;
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
uint64_t mWindowId;
};
@ -221,8 +220,8 @@ public:
GetPreviewStreamTask(CameraControlImpl* aCameraControl, dom::CameraSize aSize, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
: mSize(aSize)
, mCameraControl(aCameraControl)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraPreviewStreamCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
@ -236,7 +235,7 @@ public:
{
nsresult rv = mCameraControl->GetPreviewStreamImpl(this);
if (NS_FAILED(rv) && mOnErrorCb) {
if (NS_FAILED(rv) && mOnErrorCb.get()) {
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -245,15 +244,15 @@ public:
dom::CameraSize mSize;
nsRefPtr<CameraControlImpl> mCameraControl;
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};
// Return the autofocus status to JS. Runs on the main thread.
class AutoFocusResult : public nsRunnable
{
public:
AutoFocusResult(bool aSuccess, nsICameraAutoFocusCallback* onSuccess, uint64_t aWindowId)
AutoFocusResult(bool aSuccess, nsMainThreadPtrHandle<nsICameraAutoFocusCallback> onSuccess, uint64_t aWindowId)
: mSuccess(aSuccess)
, mOnSuccessCb(onSuccess)
, mWindowId(aWindowId)
@ -265,7 +264,7 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
mOnSuccessCb->HandleEvent(mSuccess);
}
return NS_OK;
@ -273,7 +272,7 @@ public:
protected:
bool mSuccess;
nsCOMPtr<nsICameraAutoFocusCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mOnSuccessCb;
uint64_t mWindowId;
};
@ -281,10 +280,11 @@ protected:
class AutoFocusTask : public nsRunnable
{
public:
AutoFocusTask(CameraControlImpl* aCameraControl, nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError)
AutoFocusTask(CameraControlImpl* aCameraControl, bool aCancel, nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mCancel(aCancel)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraAutoFocusCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
@ -300,7 +300,7 @@ public:
nsresult rv = mCameraControl->AutoFocusImpl(this);
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
if (NS_FAILED(rv) && mOnErrorCb) {
if (NS_FAILED(rv) && mOnErrorCb.get()) {
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -308,16 +308,19 @@ public:
}
nsRefPtr<CameraControlImpl> mCameraControl;
nsCOMPtr<nsICameraAutoFocusCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
bool mCancel;
nsMainThreadPtrHandle<nsICameraAutoFocusCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};
// Return the captured picture to JS. Runs on the main thread.
class TakePictureResult : public nsRunnable
{
public:
TakePictureResult(nsIDOMBlob* aImage, nsICameraTakePictureCallback* onSuccess, uint64_t aWindowId)
: mImage(aImage)
TakePictureResult(uint8_t* aData, uint64_t aLength, const nsAString& aMimeType, nsMainThreadPtrHandle<nsICameraTakePictureCallback> onSuccess, uint64_t aWindowId)
: mData(aData)
, mLength(aLength)
, mMimeType(aMimeType)
, mOnSuccessCb(onSuccess)
, mWindowId(aWindowId)
{
@ -334,16 +337,21 @@ public:
MOZ_ASSERT(NS_IsMainThread());
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
mOnSuccessCb->HandleEvent(mImage);
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
nsCOMPtr<nsIDOMBlob> image = new nsDOMMemoryFile(static_cast<void*>(mData), static_cast<uint64_t>(mLength), mMimeType);
mOnSuccessCb->HandleEvent(image);
} else {
delete[] mData;
}
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
return NS_OK;
}
protected:
nsCOMPtr<nsIDOMBlob> mImage;
nsCOMPtr<nsICameraTakePictureCallback> mOnSuccessCb;
uint8_t* mData;
uint64_t mLength;
nsString mMimeType;
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
uint64_t mWindowId;
};
@ -351,14 +359,15 @@ protected:
class TakePictureTask : public nsRunnable
{
public:
TakePictureTask(CameraControlImpl* aCameraControl, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mCancel(aCancel)
, mSize(aSize)
, mRotation(aRotation)
, mFileFormat(aFileFormat)
, mPosition(aPosition)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraTakePictureCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
@ -374,7 +383,7 @@ public:
nsresult rv = mCameraControl->TakePictureImpl(this);
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
if (NS_FAILED(rv) && mOnErrorCb) {
if (NS_FAILED(rv) && mOnErrorCb.get()) {
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -382,19 +391,20 @@ public:
}
nsRefPtr<CameraControlImpl> mCameraControl;
bool mCancel;
dom::CameraSize mSize;
int32_t mRotation;
nsString mFileFormat;
dom::CameraPosition mPosition;
nsCOMPtr<nsICameraTakePictureCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};
// Return the result of starting recording. Runs on the main thread.
class StartRecordingResult : public nsRunnable
{
public:
StartRecordingResult(nsICameraStartRecordingCallback* onSuccess, uint64_t aWindowId)
StartRecordingResult(nsMainThreadPtrHandle<nsICameraStartRecordingCallback> onSuccess, uint64_t aWindowId)
: mOnSuccessCb(onSuccess)
, mWindowId(aWindowId)
{ }
@ -405,14 +415,14 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
mOnSuccessCb->HandleEvent();
}
return NS_OK;
}
protected:
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
uint64_t mWindowId;
};
@ -425,8 +435,8 @@ public:
, mOptions(aOptions)
, mFolder(aFolder)
, mFilename(aFilename)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraStartRecordingCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
, mWindowId(aWindowId)
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
@ -461,8 +471,8 @@ public:
dom::CameraStartRecordingOptions mOptions;
nsCOMPtr<nsIFile> mFolder;
nsString mFilename;
nsCOMPtr<nsICameraStartRecordingCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraStartRecordingCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
uint64_t mWindowId;
};
@ -551,37 +561,6 @@ public:
nsRefPtr<CameraControlImpl> mCameraControl;
};
// Return the resulting preview stream to JS. Runs on the main thread.
class GetPreviewStreamVideoModeResult : public nsRunnable
{
public:
GetPreviewStreamVideoModeResult(nsIDOMMediaStream* aStream, nsICameraPreviewStreamCallback* onSuccess)
: mStream(aStream)
, mOnSuccessCb(onSuccess)
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
virtual ~GetPreviewStreamVideoModeResult()
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnSuccessCb) {
mOnSuccessCb->HandleEvent(mStream);
}
return NS_OK;
}
protected:
nsCOMPtr<nsIDOMMediaStream> mStream;
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
};
// Get the video mode preview stream.
class GetPreviewStreamVideoModeTask : public nsRunnable
{
@ -589,8 +568,8 @@ public:
GetPreviewStreamVideoModeTask(CameraControlImpl* aCameraControl, dom::CameraRecorderOptions aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mOptions(aOptions)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraPreviewStreamCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{ }
NS_IMETHOD Run()
@ -599,7 +578,7 @@ public:
nsresult rv = mCameraControl->GetPreviewStreamVideoModeImpl(this);
DOM_CAMERA_LOGI("%s:%d -- AFTER IMPL : rv = %d\n", __func__, __LINE__, rv);
if (NS_FAILED(rv) && mOnErrorCb) {
if (NS_FAILED(rv) && mOnErrorCb.get()) {
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -608,15 +587,15 @@ public:
nsRefPtr<CameraControlImpl> mCameraControl;
dom::CameraRecorderOptions mOptions;
nsCOMPtr<nsICameraPreviewStreamCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};
// Return the result of releasing the camera hardware. Runs on the main thread.
class ReleaseHardwareResult : public nsRunnable
{
public:
ReleaseHardwareResult(nsICameraReleaseCallback* onSuccess, uint64_t aWindowId)
ReleaseHardwareResult(nsMainThreadPtrHandle<nsICameraReleaseCallback> onSuccess, uint64_t aWindowId)
: mOnSuccessCb(onSuccess)
, mWindowId(aWindowId)
{
@ -632,14 +611,14 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnSuccessCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
if (mOnSuccessCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
mOnSuccessCb->HandleEvent();
}
return NS_OK;
}
protected:
nsCOMPtr<nsICameraReleaseCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraReleaseCallback> mOnSuccessCb;
uint64_t mWindowId;
};
@ -649,8 +628,8 @@ class ReleaseHardwareTask : public nsRunnable
public:
ReleaseHardwareTask(CameraControlImpl* aCameraControl, nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError)
: mCameraControl(aCameraControl)
, mOnSuccessCb(onSuccess)
, mOnErrorCb(onError)
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraReleaseCallback>(onSuccess))
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
}
@ -666,7 +645,7 @@ public:
nsresult rv = mCameraControl->ReleaseHardwareImpl(this);
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
if (NS_FAILED(rv) && mOnErrorCb) {
if (NS_FAILED(rv) && mOnErrorCb.get()) {
rv = NS_DispatchToMainThread(new CameraErrorResult(mOnErrorCb, NS_LITERAL_STRING("FAILURE"), mCameraControl->GetWindowId()));
NS_ENSURE_SUCCESS(rv, rv);
}
@ -674,15 +653,15 @@ public:
}
nsRefPtr<CameraControlImpl> mCameraControl;
nsCOMPtr<nsICameraReleaseCallback> mOnSuccessCb;
nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
nsMainThreadPtrHandle<nsICameraReleaseCallback> mOnSuccessCb;
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
};
// Report that the video recorder state has changed.
class CameraRecorderStateChange : public nsRunnable
{
public:
CameraRecorderStateChange(nsICameraRecorderStateChange* onStateChange, const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber, uint64_t aWindowId)
CameraRecorderStateChange(nsMainThreadPtrHandle<nsICameraRecorderStateChange> onStateChange, const nsString& aStateMsg, int32_t aStatus, int32_t aTrackNumber, uint64_t aWindowId)
: mOnStateChangeCb(onStateChange)
, mStateMsg(aStateMsg)
, mStatus(aStatus)
@ -694,7 +673,7 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
if (mOnStateChangeCb && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
if (mOnStateChangeCb.get() && nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
// For now, just pass the state message and swallow mStatus and mTrackNumber
mOnStateChangeCb->HandleStateChange(mStateMsg);
}
@ -702,7 +681,7 @@ public:
}
protected:
nsCOMPtr<nsICameraRecorderStateChange> mOnStateChangeCb;
nsMainThreadPtrHandle<nsICameraRecorderStateChange> mOnStateChangeCb;
const nsString mStateMsg;
int32_t mStatus;
int32_t mTrackNumber;

View File

@ -623,7 +623,8 @@ nsGonkCameraControl::GetPreviewStreamImpl(GetPreviewStreamTask* aGetPreviewStrea
SetPreviewSize(aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height);
DOM_CAMERA_LOGI("picture preview: wanted %d x %d, got %d x %d (%d fps, format %d)\n", aGetPreviewStream->mSize.width, aGetPreviewStream->mSize.height, mWidth, mHeight, mFps, mFormat);
nsCOMPtr<GetPreviewStreamResult> getPreviewStreamResult = new GetPreviewStreamResult(this, mWidth, mHeight, mFps, aGetPreviewStream->mOnSuccessCb, mWindowId);
nsMainThreadPtrHandle<nsICameraPreviewStreamCallback> onSuccess = aGetPreviewStream->mOnSuccessCb;
nsCOMPtr<GetPreviewStreamResult> getPreviewStreamResult = new GetPreviewStreamResult(this, mWidth, mHeight, mFps, onSuccess, mWindowId);
return NS_DispatchToMainThread(getPreviewStreamResult);
}
@ -679,20 +680,7 @@ nsGonkCameraControl::StopPreviewImpl(StopPreviewTask* aStopPreview)
nsresult
nsGonkCameraControl::AutoFocusImpl(AutoFocusTask* aAutoFocus)
{
nsCOMPtr<nsICameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb;
if (cb) {
/**
* We already have a callback, so someone has already
* called autoFocus() -- cancel it.
*/
mAutoFocusOnSuccessCb = nullptr;
nsCOMPtr<nsICameraErrorCallback> ecb = mAutoFocusOnErrorCb;
mAutoFocusOnErrorCb = nullptr;
if (ecb) {
nsresult rv = NS_DispatchToMainThread(new CameraErrorResult(ecb, NS_LITERAL_STRING("CANCELLED"), mWindowId));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aAutoFocus->mCancel) {
GonkCameraHardware::CancelAutoFocus(mHwHandle);
}
@ -747,20 +735,7 @@ nsGonkCameraControl::SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHei
nsresult
nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
{
nsCOMPtr<nsICameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
if (cb) {
/**
* We already have a callback, so someone has already
* called TakePicture() -- cancel it.
*/
mTakePictureOnSuccessCb = nullptr;
nsCOMPtr<nsICameraErrorCallback> ecb = mTakePictureOnErrorCb;
mTakePictureOnErrorCb = nullptr;
if (ecb) {
nsresult rv = NS_DispatchToMainThread(new CameraErrorResult(ecb, NS_LITERAL_STRING("CANCELLED"), mWindowId));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aTakePicture->mCancel) {
GonkCameraHardware::CancelTakePicture(mHwHandle);
}
@ -976,8 +951,7 @@ nsGonkCameraControl::TakePictureComplete(uint8_t* aData, uint32_t aLength)
memcpy(data, aData, aLength);
// TODO: see bug 779144.
nsIDOMBlob* blob = new nsDOMMemoryFile(static_cast<void*>(data), static_cast<uint64_t>(aLength), NS_LITERAL_STRING("image/jpeg"));
nsCOMPtr<nsIRunnable> takePictureResult = new TakePictureResult(blob, mTakePictureOnSuccessCb, mWindowId);
nsCOMPtr<nsIRunnable> takePictureResult = new TakePictureResult(data, aLength, NS_LITERAL_STRING("image/jpeg"), mTakePictureOnSuccessCb, mWindowId);
/**
* Remember to set these to null so that we don't hold any extra
* references to our document's window.
@ -1335,7 +1309,7 @@ nsGonkCameraControl::ReleaseHardwareImpl(ReleaseHardwareTask* aReleaseHardware)
// release the hardware handle
GonkCameraHardware::ReleaseHandle(mHwHandle, true /* unregister */);
if (aReleaseHardware && aReleaseHardware->mOnSuccessCb) {
if (aReleaseHardware) {
nsCOMPtr<nsIRunnable> releaseHardwareResult = new ReleaseHardwareResult(aReleaseHardware->mOnSuccessCb, mWindowId);
return NS_DispatchToMainThread(releaseHardwareResult);
}