Bug 1107683 - remove method callbacks from CameraControl, r=aosmond,bz

This commit is contained in:
Mike Habicher 2014-12-11 11:02:51 -05:00
parent 2fcdb603d3
commit b3d455fadf
22 changed files with 47 additions and 2547 deletions

View File

@ -68,26 +68,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl, DOMMediaStream,
mTakePicturePromise,
mStartRecordingPromise,
mReleasePromise,
mSetConfigurationPromise,
mGetCameraOnSuccessCb,
mGetCameraOnErrorCb,
mAutoFocusOnSuccessCb,
mAutoFocusOnErrorCb,
mTakePictureOnSuccessCb,
mTakePictureOnErrorCb,
mStartRecordingOnSuccessCb,
mStartRecordingOnErrorCb,
mReleaseOnSuccessCb,
mReleaseOnErrorCb,
mSetConfigurationOnSuccessCb,
mSetConfigurationOnErrorCb,
mOnShutterCb,
mOnClosedCb,
mOnRecorderStateChangeCb,
mOnPreviewStateChangeCb,
mOnAutoFocusMovingCb,
mOnAutoFocusCompletedCb,
mOnFacesDetectedCb)
mSetConfigurationPromise)
/* static */
bool
@ -207,33 +188,12 @@ nsDOMCameraControl::DiscardCachedCameraInstance(nsITimer* aTimer, void* aClosure
nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
CameraErrorCallback* aOnError,
Promise* aPromise,
nsPIDOMWindow* aWindow)
: DOMMediaStream()
, mCameraControl(nullptr)
, mAudioChannelAgent(nullptr)
, mGetCameraPromise(aPromise)
, mGetCameraOnSuccessCb(aOnSuccess)
, mGetCameraOnErrorCb(aOnError)
, mAutoFocusOnSuccessCb(nullptr)
, mAutoFocusOnErrorCb(nullptr)
, mTakePictureOnSuccessCb(nullptr)
, mTakePictureOnErrorCb(nullptr)
, mStartRecordingOnSuccessCb(nullptr)
, mStartRecordingOnErrorCb(nullptr)
, mReleaseOnSuccessCb(nullptr)
, mReleaseOnErrorCb(nullptr)
, mSetConfigurationOnSuccessCb(nullptr)
, mSetConfigurationOnErrorCb(nullptr)
, mOnShutterCb(nullptr)
, mOnClosedCb(nullptr)
, mOnRecorderStateChangeCb(nullptr)
, mOnPreviewStateChangeCb(nullptr)
, mOnAutoFocusMovingCb(nullptr)
, mOnAutoFocusCompletedCb(nullptr)
, mOnFacesDetectedCb(nullptr)
, mWindow(aWindow)
, mPreviewState(CameraControlListener::kPreviewStopped)
{
@ -665,85 +625,6 @@ nsDOMCameraControl::SensorAngle()
return angle;
}
// Callback attributes
CameraShutterCallback*
nsDOMCameraControl::GetOnShutter()
{
return mOnShutterCb;
}
void
nsDOMCameraControl::SetOnShutter(CameraShutterCallback* aCb)
{
mOnShutterCb = aCb;
}
CameraClosedCallback*
nsDOMCameraControl::GetOnClosed()
{
return mOnClosedCb;
}
void
nsDOMCameraControl::SetOnClosed(CameraClosedCallback* aCb)
{
mOnClosedCb = aCb;
}
CameraRecorderStateChange*
nsDOMCameraControl::GetOnRecorderStateChange()
{
return mOnRecorderStateChangeCb;
}
void
nsDOMCameraControl::SetOnRecorderStateChange(CameraRecorderStateChange* aCb)
{
mOnRecorderStateChangeCb = aCb;
}
CameraPreviewStateChange*
nsDOMCameraControl::GetOnPreviewStateChange()
{
return mOnPreviewStateChangeCb;
}
void
nsDOMCameraControl::SetOnPreviewStateChange(CameraPreviewStateChange* aCb)
{
mOnPreviewStateChangeCb = aCb;
}
CameraAutoFocusMovingCallback*
nsDOMCameraControl::GetOnAutoFocusMoving()
{
return mOnAutoFocusMovingCb;
}
void
nsDOMCameraControl::SetOnAutoFocusMoving(CameraAutoFocusMovingCallback* aCb)
{
mOnAutoFocusMovingCb = aCb;
}
CameraAutoFocusCallback*
nsDOMCameraControl::GetOnAutoFocusCompleted()
{
return mOnAutoFocusCompletedCb;
}
void
nsDOMCameraControl::SetOnAutoFocusCompleted(CameraAutoFocusCallback* aCb)
{
mOnAutoFocusCompletedCb = aCb;
}
CameraFaceDetectionCallback*
nsDOMCameraControl::GetOnFacesDetected()
{
return mOnFacesDetectedCb;
}
void
nsDOMCameraControl::SetOnFacesDetected(CameraFaceDetectionCallback* aCb)
{
mOnFacesDetectedCb = aCb;
}
already_AddRefed<dom::CameraCapabilities>
nsDOMCameraControl::Capabilities()
{
@ -757,35 +638,11 @@ nsDOMCameraControl::Capabilities()
return caps.forget();
}
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:
nsRefPtr<CameraErrorCallback> mCallback;
nsString mMessage;
};
// Methods.
already_AddRefed<Promise>
nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
nsDOMDeviceStorage& aStorageArea,
const nsAString& aFilename,
const Optional<OwningNonNull<CameraStartRecordingCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
@ -797,11 +654,6 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
if (mStartRecordingPromise) {
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
if (aOnError.WasPassed()) {
DOM_CAMERA_LOGT("%s:onError WasPassed\n", __func__);
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
NS_LITERAL_STRING("StartRecordingInProgress")));
}
return promise.forget();
}
@ -830,14 +682,6 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
mStartRecordingPromise = promise;
mOptions = aOptions;
mStartRecordingOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mStartRecordingOnSuccessCb = &aOnSuccess.Value();
}
mStartRecordingOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mStartRecordingOnErrorCb = &aOnError.Value();
}
nsCOMPtr<nsIDOMEventListener> listener = new StartRecordingHelper(this);
request->AddEventListener(NS_LITERAL_STRING("success"), listener, false);
@ -899,8 +743,6 @@ nsDOMCameraControl::ResumePreview(ErrorResult& aRv)
already_AddRefed<Promise>
nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
const Optional<OwningNonNull<CameraSetConfigurationCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
@ -911,14 +753,8 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
}
if (mTakePicturePromise) {
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
// We're busy taking a picture, can't change modes right now.
if (aOnError.WasPassed()) {
// There is already a call to TakePicture() in progress, abort this
// call and invoke the error callback (if one was passed in).
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
NS_LITERAL_STRING("TakePictureInProgress")));
}
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
return promise.forget();
}
@ -937,21 +773,11 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
}
mSetConfigurationPromise = promise;
mSetConfigurationOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mSetConfigurationOnSuccessCb = &aOnSuccess.Value();
}
mSetConfigurationOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mSetConfigurationOnErrorCb = &aOnError.Value();
}
return promise.forget();
}
already_AddRefed<Promise>
nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
nsDOMCameraControl::AutoFocus(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
@ -960,12 +786,6 @@ nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallba
// There is already a call to AutoFocus() in progress, cancel it and
// invoke the error callback (if one was passed in).
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
mAutoFocusOnSuccessCb = nullptr;
nsRefPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
if (ecb) {
NS_DispatchToMainThread(new ImmediateErrorCallback(ecb,
NS_LITERAL_STRING("AutoFocusInterrupted")));
}
}
promise = CreatePromise(aRv);
@ -981,14 +801,6 @@ nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallba
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
mAutoFocusPromise = promise;
mAutoFocusOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mAutoFocusOnSuccessCb = &aOnSuccess.Value();
}
mAutoFocusOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mAutoFocusOnErrorCb = &aOnError.Value();
}
return promise.forget();
}
@ -1008,8 +820,6 @@ nsDOMCameraControl::StopFaceDetection(ErrorResult& aRv)
already_AddRefed<Promise>
nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
const Optional<OwningNonNull<CameraTakePictureCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
@ -1023,10 +833,6 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
// There is already a call to TakePicture() in progress, abort this new
// one and invoke the error callback (if one was passed in).
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
if (aOnError.WasPassed()) {
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
}
return promise.forget();
}
@ -1059,21 +865,11 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
}
mTakePicturePromise = promise;
mTakePictureOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mTakePictureOnSuccessCb = &aOnSuccess.Value();
}
mTakePictureOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mTakePictureOnErrorCb = &aOnError.Value();
}
return promise.forget();
}
already_AddRefed<Promise>
nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
nsDOMCameraControl::ReleaseHardware(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
@ -1088,14 +884,6 @@ nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCa
}
mReleasePromise = promise;
mReleaseOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mReleaseOnSuccessCb = &aOnSuccess.Value();
}
mReleaseOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mReleaseOnErrorCb = &aOnError.Value();
}
return promise.forget();
}
@ -1121,27 +909,6 @@ nsDOMCameraControl::Shutdown()
AbortPromise(mStartRecordingPromise);
AbortPromise(mReleasePromise);
AbortPromise(mSetConfigurationPromise);
mGetCameraOnSuccessCb = nullptr;
mGetCameraOnErrorCb = nullptr;
mAutoFocusOnSuccessCb = nullptr;
mAutoFocusOnErrorCb = nullptr;
mTakePictureOnSuccessCb = nullptr;
mTakePictureOnErrorCb = nullptr;
mStartRecordingOnSuccessCb = nullptr;
mStartRecordingOnErrorCb = nullptr;
mReleaseOnSuccessCb = nullptr;
mReleaseOnErrorCb = nullptr;
mSetConfigurationOnSuccessCb = nullptr;
mSetConfigurationOnErrorCb = nullptr;
// Remove all of the unsolicited event handlers too.
mOnShutterCb = nullptr;
mOnClosedCb = nullptr;
mOnRecorderStateChangeCb = nullptr;
mOnPreviewStateChangeCb = nullptr;
mOnAutoFocusMovingCb = nullptr;
mOnAutoFocusCompletedCb = nullptr;
mOnFacesDetectedCb = nullptr;
mCameraControl->Shutdown();
}
@ -1236,12 +1003,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
data.mConfiguration = *mCurrentConfiguration;
promise->MaybeResolve(data);
}
nsRefPtr<GetCameraCallback> cb = mGetCameraOnSuccessCb.forget();
mGetCameraOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(*this, *mCurrentConfiguration, ignored);
}
}
break;
@ -1253,13 +1014,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
promise->MaybeResolve(JS::UndefinedHandleValue);
}
nsRefPtr<CameraReleaseCallback> rcb = mReleaseOnSuccessCb.forget();
mReleaseOnErrorCb = nullptr;
if (rcb) {
ErrorResult ignored;
rcb->Call(ignored);
}
CameraClosedEventInit eventInit;
switch (aReason) {
case NS_OK:
@ -1281,10 +1035,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
break;
}
nsRefPtr<CameraClosedCallback> cb = mOnClosedCb;
if (cb) {
cb->Call(eventInit.mReason, ignored);
}
nsRefPtr<CameraClosedEvent> event =
CameraClosedEvent::Constructor(this,
NS_LITERAL_STRING("close"),
@ -1311,13 +1061,6 @@ nsDOMCameraControl::OnShutter()
MOZ_ASSERT(NS_IsMainThread());
DOM_CAMERA_LOGI("DOM ** SNAP **\n");
nsRefPtr<CameraShutterCallback> cb = mOnShutterCb;
if (cb) {
ErrorResult ignored;
cb->Call(ignored);
}
DispatchTrustedEvent(NS_LITERAL_STRING("shutter"));
}
@ -1338,12 +1081,6 @@ nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aSt
break;
}
nsRefPtr<CameraPreviewStateChange> cb = mOnPreviewStateChangeCb;
if (cb) {
ErrorResult ignored;
cb->Call(state, ignored);
}
DispatchPreviewStateEvent(aState);
}
@ -1365,11 +1102,6 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
promise->MaybeResolve(JS::UndefinedHandleValue);
}
nsRefPtr<CameraStartRecordingCallback> scb = mStartRecordingOnSuccessCb.forget();
mStartRecordingOnErrorCb = nullptr;
if (scb) {
scb->Call(ignored);
}
state = NS_LITERAL_STRING("Started");
}
break;
@ -1410,11 +1142,6 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
return;
}
nsRefPtr<CameraRecorderStateChange> cb = mOnRecorderStateChangeCb;
if (cb) {
cb->Call(state, ignored);
}
DispatchStateEvent(NS_LITERAL_STRING("recorderstatechange"), state);
}
@ -1444,13 +1171,6 @@ nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration* aConfiguration
promise->MaybeResolve(*aConfiguration);
}
nsRefPtr<CameraSetConfigurationCallback> cb = mSetConfigurationOnSuccessCb.forget();
mSetConfigurationOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(*mCurrentConfiguration, ignored);
}
CameraConfigurationEventInit eventInit;
eventInit.mMode = mCurrentConfiguration->mMode;
eventInit.mRecorderProfile = mCurrentConfiguration->mRecorderProfile;
@ -1476,19 +1196,6 @@ nsDOMCameraControl::OnAutoFocusComplete(bool aAutoFocusSucceeded)
promise->MaybeResolve(aAutoFocusSucceeded);
}
nsRefPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb.forget();
mAutoFocusOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(aAutoFocusSucceeded, ignored);
}
cb = mOnAutoFocusCompletedCb;
if (cb) {
ErrorResult ignored;
cb->Call(aAutoFocusSucceeded, ignored);
}
if (aAutoFocusSucceeded) {
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focused"));
} else {
@ -1501,12 +1208,6 @@ nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<CameraAutoFocusMovingCallback> cb = mOnAutoFocusMovingCb;
if (cb) {
ErrorResult ignored;
cb->Call(aIsMoving, ignored);
}
if (aIsMoving) {
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
}
@ -1529,12 +1230,6 @@ nsDOMCameraControl::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces
}
}
nsRefPtr<CameraFaceDetectionCallback> cb = mOnFacesDetectedCb;
if (cb) {
ErrorResult ignored;
cb->Call(faces, ignored);
}
CameraFacesDetectedEventInit eventInit;
eventInit.mFaces.SetValue(faces);
@ -1559,14 +1254,6 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
}
nsRefPtr<File> blob = static_cast<File*>(aPicture);
nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb.forget();
mTakePictureOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(*blob, ignored);
}
BlobEventInit eventInit;
eventInit.mData = blob;
@ -1580,21 +1267,18 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
void
nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsresult aError)
{
DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, aError=0x%x\n", aContext, aError);
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<Promise> promise;
nsRefPtr<CameraErrorCallback> errorCb;
switch (aContext) {
case CameraControlListener::kInStartCamera:
promise = mGetCameraPromise.forget();
mGetCameraOnSuccessCb = nullptr;
errorCb = mGetCameraOnErrorCb.forget();
break;
case CameraControlListener::kInStopCamera:
promise = mReleasePromise.forget();
errorCb = mReleaseOnErrorCb.forget();
if (aError == NS_ERROR_NOT_INITIALIZED) {
// This value indicates that the hardware is already closed; which for
// kInStopCamera, is not actually an error.
@ -1602,41 +1286,25 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
promise->MaybeResolve(JS::UndefinedHandleValue);
}
nsRefPtr<CameraReleaseCallback> cb = mReleaseOnSuccessCb.forget();
mReleaseOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(ignored);
}
return;
}
mReleaseOnSuccessCb = nullptr;
break;
case CameraControlListener::kInSetConfiguration:
promise = mSetConfigurationPromise.forget();
mSetConfigurationOnSuccessCb = nullptr;
errorCb = mSetConfigurationOnErrorCb.forget();
break;
case CameraControlListener::kInAutoFocus:
promise = mAutoFocusPromise.forget();
mAutoFocusOnSuccessCb = nullptr;
errorCb = mAutoFocusOnErrorCb.forget();
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("unfocused"));
break;
case CameraControlListener::kInTakePicture:
promise = mTakePicturePromise.forget();
mTakePictureOnSuccessCb = nullptr;
errorCb = mTakePictureOnErrorCb.forget();
break;
case CameraControlListener::kInStartRecording:
promise = mStartRecordingPromise.forget();
mStartRecordingOnSuccessCb = nullptr;
errorCb = mStartRecordingOnErrorCb.forget();
break;
case CameraControlListener::kInStartFaceDetection:
@ -1696,57 +1364,11 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
return;
}
if (!promise && !errorCb) {
if (!promise) {
DOM_CAMERA_LOGW("DOM No error handler for aError=0x%x in aContext=%u\n",
aError, aContext);
return;
}
DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, aError=0x%x\n", aContext, aError);
if (promise) {
promise->MaybeReject(aError);
}
if (errorCb) {
nsString error;
switch (aError) {
case NS_ERROR_INVALID_ARG:
error = NS_LITERAL_STRING("InvalidArgument");
break;
case NS_ERROR_NOT_AVAILABLE:
error = NS_LITERAL_STRING("NotAvailable");
break;
case NS_ERROR_NOT_IMPLEMENTED:
error = NS_LITERAL_STRING("NotImplemented");
break;
case NS_ERROR_NOT_INITIALIZED:
error = NS_LITERAL_STRING("HardwareClosed");
break;
case NS_ERROR_ALREADY_INITIALIZED:
error = NS_LITERAL_STRING("HardwareAlreadyOpen");
break;
case NS_ERROR_OUT_OF_MEMORY:
error = NS_LITERAL_STRING("OutOfMemory");
break;
default:
{
nsPrintfCString msg("Reporting aError=0x%x as generic\n", aError);
NS_WARNING(msg.get());
}
// fallthrough
case NS_ERROR_FAILURE:
error = NS_LITERAL_STRING("GeneralFailure");
break;
}
ErrorResult ignored;
errorCb->Call(error, ignored);
}
promise->MaybeReject(aError);
}

View File

@ -55,8 +55,6 @@ public:
nsDOMCameraControl(uint32_t aCameraId,
const dom::CameraConfiguration& aInitialConfig,
dom::GetCameraCallback* aOnSuccess,
dom::CameraErrorCallback* aOnError,
dom::Promise* aPromise,
nsPIDOMWindow* aWindow);
@ -90,26 +88,8 @@ public:
double GetPictureQuality(ErrorResult& aRv);
void SetPictureQuality(double aQuality, ErrorResult& aRv);
// Unsolicited event handlers.
dom::CameraShutterCallback* GetOnShutter();
void SetOnShutter(dom::CameraShutterCallback* aCb);
dom::CameraClosedCallback* GetOnClosed();
void SetOnClosed(dom::CameraClosedCallback* aCb);
dom::CameraRecorderStateChange* GetOnRecorderStateChange();
void SetOnRecorderStateChange(dom::CameraRecorderStateChange* aCb);
dom::CameraPreviewStateChange* GetOnPreviewStateChange();
void SetOnPreviewStateChange(dom::CameraPreviewStateChange* aCb);
dom::CameraAutoFocusMovingCallback* GetOnAutoFocusMoving();
void SetOnAutoFocusMoving(dom::CameraAutoFocusMovingCallback* aCb);
dom::CameraAutoFocusCallback* GetOnAutoFocusCompleted();
void SetOnAutoFocusCompleted(dom::CameraAutoFocusCallback* aCb);
dom::CameraFaceDetectionCallback* GetOnFacesDetected();
void SetOnFacesDetected(dom::CameraFaceDetectionCallback* aCb);
// Methods.
already_AddRefed<dom::Promise> SetConfiguration(const dom::CameraConfiguration& aConfiguration,
const dom::Optional<dom::OwningNonNull<dom::CameraSetConfigurationCallback> >& aOnSuccess,
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
ErrorResult& aRv);
void GetMeteringAreas(nsTArray<dom::CameraRegion>& aAreas, ErrorResult& aRv);
void SetMeteringAreas(const dom::Optional<dom::Sequence<dom::CameraRegion> >& aAreas, ErrorResult& aRv);
@ -119,26 +99,18 @@ public:
void SetPictureSize(const dom::CameraSize& aSize, ErrorResult& aRv);
void GetThumbnailSize(dom::CameraSize& aSize, ErrorResult& aRv);
void SetThumbnailSize(const dom::CameraSize& aSize, ErrorResult& aRv);
already_AddRefed<dom::Promise> AutoFocus(const dom::Optional<dom::OwningNonNull<dom::CameraAutoFocusCallback> >& aOnSuccess,
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
ErrorResult& aRv);
already_AddRefed<dom::Promise> AutoFocus(ErrorResult& aRv);
void StartFaceDetection(ErrorResult& aRv);
void StopFaceDetection(ErrorResult& aRv);
already_AddRefed<dom::Promise> TakePicture(const dom::CameraPictureOptions& aOptions,
const dom::Optional<dom::OwningNonNull<dom::CameraTakePictureCallback> >& aOnSuccess,
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
ErrorResult& aRv);
already_AddRefed<dom::Promise> StartRecording(const dom::CameraStartRecordingOptions& aOptions,
nsDOMDeviceStorage& storageArea,
const nsAString& filename,
const dom::Optional<dom::OwningNonNull<dom::CameraStartRecordingCallback> >& aOnSuccess,
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
ErrorResult& aRv);
void StopRecording(ErrorResult& aRv);
void ResumePreview(ErrorResult& aRv);
already_AddRefed<dom::Promise> ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
ErrorResult& aRv);
already_AddRefed<dom::Promise> ReleaseHardware(ErrorResult& aRv);
void ResumeContinuousFocus(ErrorResult& aRv);
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
@ -223,29 +195,6 @@ protected:
nsRefPtr<dom::Promise> mReleasePromise;
nsRefPtr<dom::Promise> mSetConfigurationPromise;
// solicited camera control event handlers
nsRefPtr<dom::GetCameraCallback> mGetCameraOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mGetCameraOnErrorCb;
nsRefPtr<dom::CameraAutoFocusCallback> mAutoFocusOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mAutoFocusOnErrorCb;
nsRefPtr<dom::CameraTakePictureCallback> mTakePictureOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mTakePictureOnErrorCb;
nsRefPtr<dom::CameraStartRecordingCallback> mStartRecordingOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mStartRecordingOnErrorCb;
nsRefPtr<dom::CameraReleaseCallback> mReleaseOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mReleaseOnErrorCb;
nsRefPtr<dom::CameraSetConfigurationCallback> mSetConfigurationOnSuccessCb;
nsRefPtr<dom::CameraErrorCallback> mSetConfigurationOnErrorCb;
// unsolicited event handlers
nsRefPtr<dom::CameraShutterCallback> mOnShutterCb;
nsRefPtr<dom::CameraClosedCallback> mOnClosedCb;
nsRefPtr<dom::CameraRecorderStateChange> mOnRecorderStateChangeCb;
nsRefPtr<dom::CameraPreviewStateChange> mOnPreviewStateChangeCb;
nsRefPtr<dom::CameraAutoFocusMovingCallback> mOnAutoFocusMovingCb;
nsRefPtr<dom::CameraAutoFocusCallback> mOnAutoFocusCompletedCb;
nsRefPtr<dom::CameraFaceDetectionCallback> mOnFacesDetectedCb;
// Camera event listener; we only need this weak reference so that
// we can remove the listener from the camera when we're done
// with it.

View File

@ -144,24 +144,17 @@ public:
nsRefPtr<nsDOMCameraManager> aManager,
uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
nsRefPtr<GetCameraCallback> aOnSuccess,
nsRefPtr<CameraErrorCallback> aOnError,
nsRefPtr<Promise> aPromise)
: mPrincipal(aPrincipal)
, mWindow(aWindow)
, mCameraManager(aManager)
, mCameraId(aCameraId)
, mInitialConfig(aInitialConfig)
, mOnSuccess(aOnSuccess)
, mOnError(aOnError)
, mPromise(aPromise)
{
}
{ }
protected:
virtual ~CameraPermissionRequest()
{
}
virtual ~CameraPermissionRequest() { }
nsresult DispatchCallback(uint32_t aPermission);
void CallAllow();
@ -171,15 +164,10 @@ protected:
nsRefPtr<nsDOMCameraManager> mCameraManager;
uint32_t mCameraId;
CameraConfiguration mInitialConfig;
nsRefPtr<GetCameraCallback> mOnSuccess;
nsRefPtr<CameraErrorCallback> mOnError;
nsRefPtr<Promise> mPromise;
};
NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow,
mOnSuccess,
mOnError,
mPromise)
NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow, mPromise)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraPermissionRequest)
NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
@ -245,13 +233,13 @@ CameraPermissionRequest::DispatchCallback(uint32_t aPermission)
void
CameraPermissionRequest::CallAllow()
{
mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mPromise);
}
void
CameraPermissionRequest::CallCancel()
{
mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mPromise);
}
NS_IMETHODIMP
@ -275,8 +263,6 @@ nsDOMCameraManager::PreinitCameraHardware()
already_AddRefed<Promise>
nsDOMCameraManager::GetCamera(const nsAString& aCamera,
const CameraConfiguration& aInitialConfig,
const OptionalNonNullGetCameraCallback& aOnSuccess,
const OptionalNonNullCameraErrorCallback& aOnError,
ErrorResult& aRv)
{
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
@ -297,18 +283,8 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
return nullptr;
}
nsRefPtr<GetCameraCallback> successCallback;
if (aOnSuccess.WasPassed()) {
successCallback = &aOnSuccess.Value();
}
nsRefPtr<CameraErrorCallback> errorCallback;
if (aOnError.WasPassed()) {
errorCallback = &aOnError.Value();
}
if (mPermission == nsIPermissionManager::ALLOW_ACTION) {
PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
PermissionAllowed(cameraId, aInitialConfig, promise);
return promise.forget();
}
@ -324,13 +300,13 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
principal->GetAppStatus(&status);
if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
PermissionAllowed(cameraId, aInitialConfig, promise);
return promise.forget();
}
nsCOMPtr<nsIRunnable> permissionRequest =
new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig,
successCallback, errorCallback, promise);
new CameraPermissionRequest(principal, mWindow, this, cameraId,
aInitialConfig, promise);
NS_DispatchToMainThread(permissionRequest);
return promise.forget();
@ -339,8 +315,6 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
void
nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
CameraErrorCallback* aOnError,
Promise* aPromise)
{
mPermission = nsIPermissionManager::ALLOW_ACTION;
@ -348,7 +322,7 @@ nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
// Creating this object will trigger the aOnSuccess callback
// (or the aOnError one, if it fails).
nsRefPtr<nsDOMCameraControl> cameraControl =
new nsDOMCameraControl(aCameraId, aInitialConfig, aOnSuccess, aOnError, aPromise, mWindow);
new nsDOMCameraControl(aCameraId, aInitialConfig, aPromise, mWindow);
Register(cameraControl);
}
@ -356,17 +330,10 @@ nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
void
nsDOMCameraManager::PermissionCancelled(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
CameraErrorCallback* aOnError,
Promise* aPromise)
{
mPermission = nsIPermissionManager::DENY_ACTION;
aPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
if (aOnError) {
ErrorResult ignored;
aOnError->Call(NS_LITERAL_STRING("Permission denied."), ignored);
}
}
void

View File

@ -26,17 +26,11 @@ namespace mozilla {
class nsDOMCameraControl;
namespace dom {
struct CameraConfiguration;
class GetCameraCallback;
class CameraErrorCallback;
}
}
typedef nsTArray<nsRefPtr<mozilla::nsDOMCameraControl> > CameraControls;
typedef nsClassHashtable<nsUint64HashKey, CameraControls> WindowTable;
typedef mozilla::dom::Optional<mozilla::dom::OwningNonNull<mozilla::dom::GetCameraCallback> >
OptionalNonNullGetCameraCallback;
typedef mozilla::dom::Optional<mozilla::dom::OwningNonNull<mozilla::dom::CameraErrorCallback> >
OptionalNonNullCameraErrorCallback;
class nsDOMCameraManager MOZ_FINAL
: public nsIObserver
@ -66,28 +60,21 @@ public:
void PermissionAllowed(uint32_t aCameraId,
const mozilla::dom::CameraConfiguration& aOptions,
mozilla::dom::GetCameraCallback* aOnSuccess,
mozilla::dom::CameraErrorCallback* aOnError,
mozilla::dom::Promise* aPromise);
void PermissionCancelled(uint32_t aCameraId,
const mozilla::dom::CameraConfiguration& aOptions,
mozilla::dom::GetCameraCallback* aOnSuccess,
mozilla::dom::CameraErrorCallback* aOnError,
mozilla::dom::Promise* aPromise);
// WebIDL
already_AddRefed<mozilla::dom::Promise>
GetCamera(const nsAString& aCamera,
const mozilla::dom::CameraConfiguration& aOptions,
const OptionalNonNullGetCameraCallback& aOnSuccess,
const OptionalNonNullCameraErrorCallback& aOnError,
mozilla::ErrorResult& aRv);
void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
nsPIDOMWindow* GetParentObject() const { return mWindow; }
virtual JSObject* WrapObject(JSContext* aCx)
MOZ_OVERRIDE;
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
#ifdef MOZ_WIDGET_GONK
static void PreinitCameraHardware();

View File

@ -1,97 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for bug 1022766</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var config = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
function onError(e) {
ok(false, "Error" + JSON.stringify(e));
}
var Camera = {
cameraObj: null,
_otherPictureSize: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
firstCallFailed: false,
secondCallSucceeded: false,
checkForDone: function test_checkForDone() {
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
Camera.cameraObj.release();
Camera.cameraObj = null;
CameraTest.end();
}
},
successOne: function test_successOne(focused) {
ok(false, "First call to autoFocus() succeeded unexpectedly");
},
failureOne: function test_failureOne(error) {
ok(error == "AutoFocusInterrupted", "First call to autoFocus() failed with: "
+ error);
Camera.firstCallFailed = true;
Camera.checkForDone();
},
successTwo: function test_successTwo(focused) {
ok(true, "Second call to autoFocus() succeeded");
Camera.secondCallSucceeded = true;
Camera.checkForDone();
},
failureTwo: function test_failureTwo(error) {
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
},
start: function test_start() {
function onSuccess(camera, config) {
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
// It doesn't matter if the emulator supports focus or not;
// this is just testing the sequencing.
camera.autoFocus(Camera.successOne, Camera.failureOne);
camera.autoFocus(Camera.successTwo, Camera.failureTwo);
};
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
}
}
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
if (Camera.cameraObj) {
Camera.cameraObj.release();
Camera.cameraObj = null;
}
});
CameraTest.begin("hardware", function(test) {
test.set("auto-focus-process-failure", function() {
Camera.start();
})
});
</script>
</body>
</html>

View File

@ -1,107 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for bug 1099390</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var config = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
function onError(e) {
ok(false, "Error " + e);
}
var Camera = {
_cameraObj: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
release: function release() {
viewfinder.mozSrcObject = null;
if (Camera._cameraObj) {
Camera._cameraObj.release();
Camera._cameraObj = null;
}
},
test: function test(cam) {
var gotCloseEvent = false;
var gotReleaseCallback = false;
function gotAll() {
var all = gotCloseEvent && gotReleaseCallback;
if (all) {
info("Got all expected notifications");
}
return all;
};
cam.onClosed = function(reason) {
cam.onClosed = null;
ok(!gotCloseEvent, "gotCloseEvent was " + gotCloseEvent);
ok(reason === "HardwareReleased", "onClosed reason is: " + reason);
gotCloseEvent = true;
if (gotAll()) {
SimpleTest.finish();
}
};
var onSuccess = function() {
ok(!gotReleaseCallback, "gotReleaseCallback was " + gotReleaseCallback);
gotReleaseCallback = true;
if (gotAll()) {
SimpleTest.finish();
}
};
cam.release(onSuccess, onError);
}, // test()
start: function start() {
function onSuccess(cam) {
Camera._cameraObj = cam;
Camera.viewfinder.mozSrcObject = cam;
Camera.viewfinder.play();
var onPreviewStateChange = function(e) {
if (e.newState === 'started') {
cam.removeEventListener('previewstatechange', onPreviewStateChange);
Camera.test(cam);
}
}; // onPreviewStateChange
cam.addEventListener('previewstatechange', onPreviewStateChange);
}; // onSuccess()
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
}, // start()
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.release();
});
Camera.start();
</script>
</body>
</html>

View File

@ -1,223 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for bug 975472</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var config = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
var options = {
rotation: 0,
position: {
latitude: 43.645687,
longitude: -79.393661
},
dateTime: Date.now()
};
function onError(e) {
ok(false, "Error" + JSON.stringify(e));
}
function next() {
Camera.nextTest();
}
// The array of tests
var tests = [
{
key: "release-after-release",
func: function testAutoFocus(camera) {
function onSuccess(success) {
ok(true, "release() succeeded");
next();
}
function onError(error) {
ok(false, "release() failed with: " + error);
}
camera.release(onSuccess, onError);
}
},
{
key: "set-picture-size-after-release",
func: function testSetPictureSize(camera) {
camera.setPictureSize({ width: 0, height: 0 });
next();
}
},
{
key: "set-thumbnail-size-after-release",
func: function testSetThumbnailSize(camera) {
camera.setThumbnailSize({ width: 0, height: 0 });
next();
}
},
{
key: "get-sensor-angle-after-release",
func: function testGetSensorAngle(camera) {
ok(camera.sensorAngle == 0, "camera.sensorAngle = " + camera.sensorAngle);
next();
}
},
{
key: "resume-preview-after-release",
func: function testResumePreview(camera) {
camera.resumePreview();
next();
}
},
{
key: "auto-focus-after-release",
func: function testAutoFocus(camera) {
function onSuccess(success) {
ok(false, "autoFocus() succeeded incorrectly");
}
function onError(error) {
ok(error === "HardwareClosed", "autoFocus() failed with: " + error);
next();
}
camera.autoFocus(onSuccess, onError);
}
},
{
key: "take-picture-after-release",
func: function testTakePicture(camera) {
function onSuccess(picture) {
ok(false, "takePicture() succeeded incorrectly");
}
function onError(error) {
ok(error === "HardwareClosed", "takePicture() failed with: " + error);
next();
}
camera.takePicture(null, onSuccess, onError);
}
},
{
key: "start-recording-after-release",
func: function testStartRecording(camera) {
function onSuccess(picture) {
ok(false, "startRecording() process succeeded incorrectly");
}
function onError(error) {
ok(error === "GeneralFailure", "startRecording() failed with: " + error);
next();
}
var recordingOptions = {
profile: 'cif',
rotation: 0
};
camera.startRecording(recordingOptions,
navigator.getDeviceStorage('videos'),
'bug975472.mp4',
onSuccess, onError);
}
},
{
key: "stop-recording-after-release",
func: function testStopRecording(camera) {
camera.stopRecording();
next();
}
},
{
key: "set-configuration-after-release",
func: function testSetConfiguration(camera) {
function onSuccess(picture) {
ok(false, "setConfiguration() process succeeded incorrectly");
}
function onError(error) {
ok(error === "HardwareClosed", "setConfiguration() failed with: " + error);
next();
}
camera.setConfiguration(config, onSuccess, onError);
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
var Camera = {
cameraObj: null,
_otherPictureSize: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
onCameraReady: function () {
Camera.nextTest = function() {
try {
var t = testGenerator.next();
info("test: " + t.key);
t.func(Camera.cameraObj);
} catch(e) {
if (e instanceof StopIteration) {
CameraTest.end();
} else {
throw e;
}
}
};
// Release the camera hardware, and call all of the asynchronous methods
// to make sure they properly handle being in this state.
Camera.cameraObj.release();
next();
},
release: function release() {
cameraObj = null;
},
start: function run_test() {
function onSuccess(camera, config) {
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
ok(camera.capabilities.pictureSizes.length > 0,
"capabilities.pictureSizes.length = " +
camera.capabilities.pictureSizes.length);
Camera._otherPictureSize = camera.capabilities.pictureSizes.slice(-1)[0];
camera.setPictureSize(camera.capabilities.pictureSizes[0]);
options.pictureSize = Camera._otherPictureSize;
options.fileFormat = camera.capabilities.fileFormats[0];
info("getCamera callback, setting pictureSize = " + options.pictureSize.toSource());
Camera.cameraObj.onPreviewStateChange = function(state) {
if (state === 'started') {
info("viewfinder is ready and playing");
Camera.cameraObj.onPreviewStateChange = null;
Camera.onCameraReady();
}
};
};
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
Camera.cameraObj = null;
});
Camera.start();
</script>
</body>
</html>

View File

@ -1,242 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for mozCameras.getCamera() with separate .setConfiguration() call</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var options = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
var config = {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
};
function onError(e) {
ok(false, "Error" + JSON.stringify(e));
}
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
'recorderProfiles', 'zoomRatios', 'isoModes'];
var Camera = {
cameraObj: null,
_recording: false,
_currentTest: null,
_autoFocusSupported: 0,
_manuallyFocused: false,
_flashmodes: null,
_pictureSizes: null,
_previewSizes: null,
_whiteBalanceModes: null,
_zoomRatios: null,
_sceneModes: null,
_focusModes: null,
_zoomRatios: null,
_testsCompleted: 0,
_shutter: 0,
_config: {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
},
_tests: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
setFlashMode: function camera_setFlash(mode) {
this.cameraObj.flashMode = mode;
},
setFocus: function camera_setfocus(mode) {
this.cameraObj.focus = mode;
},
setZoom: function camera_setZoom(zoom) {
this.cameraObj.zoom = zoom;
},
getZoom: function camera_getZoom() {
return this.cameraObj.zoom;
},
getFileFormats: function camera_formats() {
this._fileFormats = this.cameraObj.capabilities.fileFormats;
},
getFlashModes: function camera_getFlash() {
this._flashmodes = this.cameraObj.capabilities.flashModes;
},
getFocusModes: function camera_getFocus() {
this._focusModes = this.cameraObj.capabilities.focusModes;
},
getSceneModes: function camera_getScene() {
this._sceneModes = this.cameraObj.capabilities.sceneModes;
},
getZoomRatios: function camera_getZoom() {
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
},
getWhiteBalance: function camera_white() {
this._whitebalanceModes = this.cameraObj.capabilities.whiteBalanceModes;
},
getPictureSizes: function camera_sizes() {
this._pictureSizes = this.cameraObj.capabilities.pictureSizes;
},
getPreviewSizes: function camera_preview() {
this._previewSizes = this.cameraObj.capabilities.previewSizes;
},
getZoomRatios: function camera_preview() {
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
},
takePictureSuccess: function taken_foto(blob) {
var img = new Image();
var test = this._currentTest;
img.onload = function Imgsize() {
ok(this.width == test.pictureSize.width, "The image taken has the width " +
this.width + " pictureSize width = " + test.pictureSize.width);
ok(this.height == test.pictureSize.height, "The image taken has the height " +
this.height + " picturesize height = " + test.pictureSize.height);
Camera._testsCompleted++;
if(Camera._testsCompleted == Camera._tests.length) {
ok(true, "test finishing");
SimpleTest.finish();
} else {
Camera.runTests();
}
}
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
img.src = window.URL.createObjectURL(blob);
},
shutter: function onShutter () {
Camera._shutter++;
ok(Camera._shutter == (Camera._testsCompleted + 1), "on Shutter has been called " +
Camera._shutter + " times");
},
onReady: function onReady() {
var camcap = Camera.cameraObj.capabilities;
var tests = {};
for (var prop in capabilities) {
prop = capabilities[prop];
ok(camcap[prop] || isFinite(camcap[prop]) || camcap[prop] == null, "Camera Capability: " +
prop + " is exposed, value = " + JSON.stringify(camcap[prop]));
}
ok(camcap.maxMeteringAreas >= 0, "maxMeteringAreas = " + camcap.maxMeteringAreas);
ok(camcap.maxFocusAreas >= 0, "maxFocusAreas = " + camcap.maxFocusAreas);
for (var prop in camcap) {
if(camcap[prop] && camcap[prop].length > 1) {
tests[prop] = camcap[prop];
}
}
Camera.getPictureSizes();
Camera.getPreviewSizes();
Camera.getFileFormats();
Camera.getFocusModes();
Camera.getZoomRatios();
ok(Camera._previewSizes.length > 0, "previewSizes length = " + Camera._previewSizes.length);
ok(Camera._pictureSizes.length > 0, "picturesizes length = " + Camera._pictureSizes.length);
ok(Camera._fileFormats.length > 0, "file formats length = " + Camera._fileFormats.length);
ok(camcap.isoModes.length == 0, "ISO modes length = " + camcap.isoModes.length);
// The emulator doesn't support zoom, so these parameters will be very constrained
// For more ambitious tests, see test_camera_fake_parameters.html
ok(Camera._zoomRatios.length == 1, "zoom ratios length = " + Camera._zoomRatios.length);
ok(Camera.cameraObj.zoom == 1.0, "zoom = " + Camera.cameraObj.zoom);
// Test snapping to supported values
Camera.cameraObj.zoom = 0.9;
ok(Camera.cameraObj.zoom == 1.0, "zoom (lower limit) = " + Camera.cameraObj.zoom);
Camera.cameraObj.zoom = 1.1;
ok(Camera.cameraObj.zoom == 1.0, "zoom (upper limit) = " + Camera.cameraObj.zoom);
// Check image quality handling
Camera.cameraObj.pictureQuality = 0.0;
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality = " + Camera.cameraObj.pictureQuality);
Camera.cameraObj.pictureQuality = -0.1;
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality (minimum limit) = " + Camera.cameraObj.pictureQuality);
Camera.cameraObj.pictureQuality = -Math.pow(2, 80);
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality (BIG negative) = " + Camera.cameraObj.pictureQuality);
Camera.cameraObj.pictureQuality = 1.0;
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality = " + Camera.cameraObj.pictureQuality);
Camera.cameraObj.pictureQuality = 1.1;
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality (maximum limit) = " + Camera.cameraObj.pictureQuality);
Camera.cameraObj.pictureQuality = Math.pow(2, 80);
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality (BIG positive) = " + Camera.cameraObj.pictureQuality);
Camera._tests = new Array();
for (var i in Camera._pictureSizes) {
for (var l in Camera._fileFormats) {
var config = {
pictureSize: Camera._pictureSizes[i],
fileFormat: Camera._fileFormats[l]
};
Camera._tests.push(config);
}
}
Camera.runTests();
},
runTests: function run_tests() {
var test = this._tests[this._testsCompleted];
this._currentTest = test;
Camera.setFlashMode(test.flashMode);
config.fileFormat = test.fileFormat;
config.pictureSize = test.pictureSize;
ok(true, "testing picture size " + JSON.stringify(config.pictureSize));
Camera.cameraObj.takePicture(config, this.takePictureSuccess.bind(this), onError);
},
onConfigChange: function onConfigChange(config) {
ok(config.mode === options.mode, "configuration mode = " + config.mode);
ok(config.recorderProfile === options.recorderProfile, "recorder profile = " + config.recorderProfile);
ok(config.previewSize.width === options.previewSize.width &&
config.previewSize.height === options.previewSize.height,
"preview size (w x h) = " + config.previewSize.width + " x " + config.previewSize.height);
},
setUp: function setup_tests() {
function onSuccess(camera) {
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
Camera.cameraObj.onPreviewStateChange = function(state) {
if (state === 'started') {
ok(true, "viewfinder is ready and playing");
Camera.cameraObj.onPreviewStateChange = null;
Camera.onReady();
}
};
SimpleTest.expectAssertions(0);
ok(true, "Camera Control object has been successfully initialized");
Camera.cameraObj.setConfiguration(options, Camera.onConfigChange, onError);
Camera.cameraObj.onShutter = Camera.shutter;
};
navigator.mozCameras.getCamera(whichCamera, null, onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
Camera.cameraObj = null;
});
Camera.setUp();
</script>
</body>
</html>

View File

@ -1,200 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for mozCameras.getCamera() using an initial configuration</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var options = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
var config = {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
};
function onError(e) {
ok(false, "Error" + JSON.stringify(e));
}
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
'recorderProfiles'];
var Camera = {
cameraObj: null,
_recording: false,
_currentTest: null,
_autoFocusSupported: 0,
_manuallyFocused: false,
_flashmodes: null,
_pictureSizes: null,
_previewSizes: null,
_whiteBalanceModes: null,
_zoomRatios: null,
_sceneModes: null,
_focusModes: null,
_testsCompleted: 0,
_shutter: 0,
_config: {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
},
_tests: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
setFlashMode: function camera_setFlash(mode) {
this.cameraObj.flashMode = mode;
},
setFocus: function camera_setfocus(mode) {
this.cameraObj.focus = mode;
},
getFileFormats: function camera_formats() {
this._fileFormats = this.cameraObj.capabilities.fileFormats;
},
getFlashModes: function camera_getFlash() {
this._flashmodes = this.cameraObj.capabilities.flashModes;
},
getFocusModes: function camera_getFocus() {
this._focusModes = this.cameraObj.capabilities.focusModes;
},
getSceneModes: function camera_getScene() {
this._sceneModes = this.cameraObj.capabilities.sceneModes;
},
getZoomRatios: function camera_getZoom() {
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
},
getWhiteBalance: function camera_white() {
this._whitebalanceModes = this.cameraObj.capabilities.whiteBalanceModes;
},
getPictureSizes: function camera_sizes() {
this._pictureSizes = this.cameraObj.capabilities.pictureSizes;
},
getPreviewSizes: function camera_preview() {
this._previewSizes = this.cameraObj.capabilities.previewSizes;
},
takePictureSuccess: function taken_foto(blob) {
var img = new Image();
var test = this._currentTest;
img.onload = function Imgsize() {
ok(this.width == test.pictureSize.width, "The image taken has the width " +
this.width + " pictureSize width = " + test.pictureSize.width);
ok(this.height == test.pictureSize.height, "The image taken has the height " +
this.height + " picturesize height = " + test.pictureSize.height);
Camera._testsCompleted++;
if(Camera._testsCompleted == Camera._tests.length) {
ok(true, "test finishing");
SimpleTest.finish();
} else {
Camera.runTests();
}
}
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
img.src = window.URL.createObjectURL(blob);
},
shutter: function onShutter () {
Camera._shutter++;
ok(Camera._shutter == (Camera._testsCompleted + 1), "on Shutter has been called " +
Camera._shutter + " times");
},
onReady: function onReady() {
var camcap = Camera.cameraObj.capabilities;
var tests = {};
for (var prop in capabilities) {
prop = capabilities[prop];
ok(camcap[prop] || isFinite(camcap[prop]) || camcap[prop] == null, "Camera Capability: " +
prop + " is exposed, value = " + JSON.stringify(camcap[prop]));
}
for (var prop in camcap) {
if(camcap[prop] && camcap[prop].length > 1) {
tests[prop] = camcap[prop];
}
}
Camera.getPictureSizes();
Camera.getPreviewSizes();
Camera.getFileFormats();
Camera.getFocusModes();
ok(Camera._previewSizes.length > 0, "previewSizes length = " + Camera._previewSizes.length);
ok(Camera._pictureSizes.length > 0, "picturesizes length = " + Camera._pictureSizes.length);
ok(Camera._fileFormats.length > 0, "file formats length = " + Camera._fileFormats.length);
Camera._tests = new Array();
for (var i in Camera._pictureSizes) {
for (var l in Camera._fileFormats) {
var config = {
pictureSize: Camera._pictureSizes[i],
fileFormat: Camera._fileFormats[l]
};
Camera._tests.push(config);
}
}
Camera.runTests();
},
runTests: function run_tests() {
var test = this._tests[this._testsCompleted];
this._currentTest = test;
Camera.setFlashMode(test.flashMode);
config.fileFormat = test.fileFormat;
config.pictureSize = test.pictureSize;
ok(true, "testing picture size " + JSON.stringify(config.pictureSize));
Camera.cameraObj.takePicture(config, this.takePictureSuccess.bind(this), onError);
},
setUp: function setup_tests() {
function onSuccess(camera, config) {
ok(true, "Camera Control object has been successfully initialized");
ok(config.mode === options.mode, "configuration mode = " + config.mode);
ok(config.recorderProfile === options.recorderProfile, "recorder profile = " + config.recorderProfile);
ok(config.previewSize.width === options.previewSize.width &&
config.previewSize.height === options.previewSize.height,
"preview size (w x h) = " + config.previewSize.width + " x " + config.previewSize.height);
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
Camera.cameraObj.onPreviewStateChange = function(state) {
if (state === 'started') {
ok(true, "viewfinder is ready and playing");
Camera.cameraObj.onPreviewStateChange = null;
Camera.onReady();
}
};
SimpleTest.expectAssertions(0);
Camera.cameraObj.onShutter = Camera.shutter;
};
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
Camera.cameraObj = null;
});
Camera.setUp();
</script>
</body>
</html>

View File

@ -1,76 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for multiple calls to mozCameras.getCamera()</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var options = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
function onError(e) {
ok(false, "Error" + JSON.stringify(e));
}
var Camera = {
cameraObj: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
onReady: function take_two() {
function onSuccess(camera, config) {
ok(false, "Unexpectedly got second camera instance: " + config.toSource);
}
function onFailure(error) {
ok(true, "Correctly failed to get camera again");
SimpleTest.finish();
}
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onFailure);
},
release: function release() {
cameraObj = null;
},
start: function run_test() {
function onSuccess(camera, config) {
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
Camera.cameraObj.onPreviewStateChange = function(state) {
if (state === 'started') {
ok(true, "viewfinder is ready and playing");
Camera.cameraObj.onPreviewStateChange = null;
Camera.onReady();
}
};
};
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
Camera.cameraObj = null;
});
Camera.start();
</script>
</body>
</html>

View File

@ -1,131 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=965421
-->
<head>
<title>Bug 965421 - Test camera hardware API for Auto focus moving Callback</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965421">Mozilla Bug 965421</a>
<video id="viewfinder" width = "200" height = "200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
const PREF_AUTOFOCUSCALLBACK_ENABLED = "camera.control.autofocus_moving_callback.enabled";
var cameraObj;
var oldPref;
// Shorthand functions
function end() {
function reallyEnd() {
CameraTest.end();
}
if (oldPref) {
SpecialPowers.pushPrefEnv(
{'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, oldPref]]}, reallyEnd);
} else {
SpecialPowers.pushPrefEnv(
{'clear': [[PREF_AUTOFOCUSCALLBACK_ENABLED]]}, reallyEnd);
}
}
function next() {
CameraTest.next();
}
var tests = [
{
key: "autofocus-moving-true",
func: function testAutoFocusMovingIsTrue(camera) {
camera.onAutoFocusMoving = function(aIsMoving) {
ok(aIsMoving == true,"onAutoFocusMoving callback received true correctly");
camera.focusMode = 'auto';
next();
}
camera.focusMode = 'continuous-picture';
}
},
{
key: "autofocus-moving-false",
func: function testAutoFocusMovingIsFalse(camera) {
camera.onAutoFocusMoving = function(aIsMoving) {
ok(aIsMoving == false, "onAutoFocusMoving callback received false correctly");
camera.focusMode = 'auto';
end();
}
camera.focusMode = 'continuous-video';
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
window.addEventListener('beforeunload', function() {
document.getElementById('viewfinder').mozSrcObject = null;
cameraObj.release();
cameraObj = null;
});
// Must call CameraTest.begin() before any other async methods.
CameraTest.begin("hardware", function(test) {
// If the pref doesn't exist, this get will fail; catch it and continue.
try {
oldPref = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
} catch(e) { }
SpecialPowers.pushPrefEnv({'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, true]]}, function() {
var enabled;
try {
enabled = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
} catch(e) { }
ok(enabled, PREF_AUTOFOCUSCALLBACK_ENABLED + " is " + enabled);
function onSuccess(camera, config) {
document.getElementById('viewfinder').mozSrcObject = camera;
cameraObj = camera;
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, camera));
} catch(e) {
if (e instanceof StopIteration) {
end();
} else {
throw e;
}
}
};
next();
}
function onError(error) {
ok(false, "getCamera() failed with: " + error);
end();
}
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
})
});
</script>
</body>
</html>

View File

@ -1,320 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=965420
-->
<head>
<title>Bug 965420 - Test camera hardware API for face detection</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965420">Mozilla Bug 965420</a>
<video id="viewfinder" width = "200" height = "200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
const PREF_FACEDETECTION_ENABLED = "camera.control.face_detection.enabled";
var cameraObj;
var oldPref;
// Shorthand functions
function end() {
function reallyEnd() {
CameraTest.end();
}
if (oldPref) {
SpecialPowers.pushPrefEnv(
{'set': [[PREF_FACEDETECTION_ENABLED, oldPref]]}, reallyEnd);
} else {
SpecialPowers.pushPrefEnv(
{'clear': [[PREF_FACEDETECTION_ENABLED]]}, reallyEnd);
}
}
function next() {
CameraTest.next();
}
function compareFaces(aFaces, expected)
{
ok(aFaces, "have detected faces object");
ok(aFaces.length == expected.faces.length,
"expected=" + expected.faces.length + ", got=" + aFaces.length);
aFaces.forEach(function (face, index) {
let result = compareFace(face, expected.faces[index]);
ok(result === "ok", "face check: " + result);
if (result !== "ok") {
return false;
}
});
return true;
}
function compareFace(aFace, expected)
{
if (aFace.id != expected.id) {
return "expected face.id=" + expected.id + ", got=" + aFace.id;
}
if (aFace.score != expected.score) {
return "expected face.score=" + expected.score + ", got=" + aFace.score;
}
if (!aFace.bounds) {
return "face.bounds is missing";
}
if (aFace.bounds.left != expected.bounds.left ||
aFace.bounds.top != expected.bounds.top ||
aFace.bounds.right != expected.bounds.right ||
aFace.bounds.bottom != expected.bounds.bottom) {
return "expected face.bounds=" + expected.bounds.toSource() +
", got=({left:" + aFace.bounds.left + ", top:" + aFace.bounds.top + ", right:" + aFace.bounds.right + ", bottom:" + aFace.bounds.bottom + "})";
}
if (aFace.leftEye && !expected.leftEye) {
return "expected null face.leftEye, got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
}
if (!aFace.leftEye && expected.leftEye) {
return "expected face.leftEye=" + expected.leftEye.toSource() + ", got null leftEye";
}
if (aFace.leftEye && expected.leftEye &&
(aFace.leftEye.x != expected.leftEye.x || aFace.leftEye.y != expected.leftEye.y)) {
return "expected face.leftEye=" + expected.leftEye.toSource() +
", got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
}
if (aFace.rightEye && !expected.rightEye) {
return "expected null face.rightEye, got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
}
if (!aFace.rightEye && expected.rightEye) {
return "expected face.rightEye=" + expected.rightEye.toSource() + ", got null rightEye";
}
if (aFace.rightEye && expected.rightEye &&
(aFace.rightEye.x != expected.rightEye.x || aFace.rightEye.y != expected.rightEye.y)) {
return "expected face.rightEye=" + expected.rightEye.toSource() +
", got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
}
if (aFace.mouth && !expected.mouth) {
return "expected null face.mouth, got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
}
if (!aFace.mouth && expected.mouth) {
return "expected face.mouth=" + expected.mouth.toSource() + ", got null mouth";
}
if (aFace.mouth && expected.mouth &&
(aFace.mouth.x != expected.mouth.x || aFace.mouth.y != expected.mouth.y)) {
return "expected face.mouth=" + expected.mouth.toSource() +
", got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
}
return "ok";
}
var tests = [
{
key: "face-detection-detected-one-face",
func: function testFaceDetectionFoundOneFace(camera) {
var expected = {
faces: [ {
id: 1,
score: 2,
bounds: {
left: 3,
top: 4,
right: 5,
bottom: 6
},
leftEye: {
x: 7,
y: 8
},
rightEye: {
x: 9,
y: 10
},
mouth: {
x: 11,
y: 12
}
} ]
};
camera.onFacesDetected = function(aFaces) {
ok(compareFaces(aFaces, expected),
"onFaceDetected received the detected faces correctly");
camera.stopFaceDetection();
next();
}
camera.startFaceDetection();
}
},
{
key: "face-detection-detected-two-faces",
func: function testFaceDetectionFoundTwoFace(camera) {
var expected = {
faces: [ {
id: 1,
score: 2,
bounds: {
left: 3,
top: 4,
right: 5,
bottom: 6
},
leftEye: {
x: 7,
y: 8
},
rightEye: {
x: 9,
y: 10
},
mouth: {
x: 11,
y: 12
}
},
{
id: 13,
score: 14,
bounds: {
left: 15,
top: 16,
right: 17,
bottom: 18
},
leftEye: {
x: 19,
y: 20
},
rightEye: {
x: 21,
y: 22
},
mouth: {
x: 23,
y: 24
}
} ]
};
camera.onFacesDetected = function(aFaces) {
ok(compareFaces(aFaces, expected),
"onFaceDetected received the detected faces correctly");
camera.stopFaceDetection();
next();
}
camera.startFaceDetection();
}
},
{
key: "face-detection-detected-one-face-no-features",
func: function (camera) {
var expected = {
faces: [ {
id: 1,
score: 100,
bounds: {
left: 3,
top: 4,
right: 5,
bottom: 6
},
leftEye: null,
rightEye: null,
mouth: null
} ]
};
camera.onFacesDetected = function(aFaces) {
ok(compareFaces(aFaces, expected),
"onFaceDetected received the detected faces correctly");
camera.stopFaceDetection();
next();
}
camera.startFaceDetection();
}
},
{
key: "face-detection-no-faces-detected",
func: function (camera) {
var expected = {
faces: []
};
camera.onFacesDetected = function(aFaces) {
ok(compareFaces(aFaces, expected),
"onFaceDetected received the detected faces correctly");
camera.stopFaceDetection();
next();
}
camera.startFaceDetection();
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
window.addEventListener('beforeunload', function() {
document.getElementById('viewfinder').mozSrcObject = null;
if (cameraObj) {
cameraObj.release();
cameraObj = null;
}
});
// Must call CameraTest.begin() before any other async methods.
CameraTest.begin("hardware", function(test) {
// If the pref doesn't exist, this get will fail; catch it and continue.
try {
oldPref = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
} catch(e) { }
SpecialPowers.pushPrefEnv({'set': [[PREF_FACEDETECTION_ENABLED, true]]}, function() {
var enabled;
try {
enabled = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
} catch(e) { }
ok(enabled, PREF_FACEDETECTION_ENABLED + " is " + enabled);
function onSuccess(camera, config) {
document.getElementById('viewfinder').mozSrcObject = camera;
cameraObj = camera;
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, camera));
} catch(e) {
if (e instanceof StopIteration) {
end();
} else {
throw e;
}
}
};
next();
}
function onError(error) {
ok(false, "getCamera() failed with: " + error);
end();
}
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
})
});
</script>
</body>
</html>

View File

@ -1,145 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
-->
<head>
<title>Bug 940424 - Test camera hardware API failure handling</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
<video id="viewfinder" width = "200" height = "200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
var cameraObj;
// Shorthand functions
function end() {
CameraTest.end();
}
function next() {
CameraTest.next();
}
// The array of tests
var tests = [
{
key: "auto-focus-failure",
func: function testAutoFocusApiFailure(camera) {
function onSuccess(success) {
ok(false, "autoFocus() succeeded incorrectly");
end();
}
function onError(error) {
ok(true, "autoFocus() failed correctly with: " + error);
next();
}
camera.autoFocus(onSuccess, onError);
}
},
{
key: "auto-focus-process-failure",
func: function testAutoFocusProcessFailure(camera) {
function onSuccess(success) {
if (success) {
ok(false, "autoFocus() process succeeded incorrectly");
end();
} else {
ok(true, "autoFocus() process failed correctly");
next();
}
}
function onError(error) {
ok(false, "autoFocus() process failed incorrectly with: " + error);
end();
}
camera.autoFocus(onSuccess, onError);
}
},
{
key: "take-picture-failure",
func: function testTakePictureApiFailure(camera) {
function onSuccess(picture) {
ok(false, "takePicture() succeeded incorrectly");
end();
}
function onError(error) {
ok(true, "takePicture() failed correctly with: " + error);
next();
}
camera.takePicture(null, onSuccess, onError);
}
},
{
key: "take-picture-process-failure",
func: function testTakePictureProcessFailure(camera) {
function onSuccess(picture) {
ok(false, "takePicture() process succeeded incorrectly");
end();
}
function onError(error) {
ok(true, "takePicture() process failed correctly with: " + error);
next();
}
camera.takePicture(null, onSuccess, onError);
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
}();
window.addEventListener('beforeunload', function() {
document.getElementById('viewfinder').mozSrcObject = null;
cameraObj.release();
cameraObj = null;
});
CameraTest.begin("hardware", function(test) {
function onSuccess(camera, config) {
document.getElementById('viewfinder').mozSrcObject = camera;
cameraObj = camera;
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, camera));
} catch(e) {
if (e instanceof StopIteration) {
end();
} else {
throw e;
}
}
};
next();
}
function onError(error) {
ok(false, "getCamera() failed with: " + error);
end();
}
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
});
</script>
</body>
</html>

View File

@ -1,149 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
-->
<head>
<title>Bug 940424 - Test camera hardware init failure handling</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="../camera_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
<video id="viewfinder" width="200" height="200" autoplay></video>
<img src="#" alt="This image is going to load" id="testimage"/>
<script class="testbody" type="text/javascript;version=1.7">
SimpleTest.waitForExplicitFinish();
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
var initialConfig = {
mode: 'picture',
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
var tests = [
{
name: "init-failure",
key: "init-failure",
func: function testInitFailure(test) {
function onSuccess(camera, config) {
ok(false, "onSuccess called incorrectly");
camera.release();
test.next();
}
function onError(error) {
ok(true, "onError called correctly on init failure");
test.next();
}
info("Running test: init-failure");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
}
},
/* This test case (init-success) *must* follow the preceeding test case
(init-failure) in order for the desired condition to be verified */
{
name: "init-success",
key: "",
func: function(test) {
function onSuccess(camera, config) {
ok(true, "onSuccess called correctly");
camera.release();
test.next();
}
function onError(error) {
ok(false, "onError called incorrectly: " + error);
test.next();
}
info("Running test: init-success");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError)
}
},
/* Test for bug 1099390 to make sure events related to the underlying
platform failing are generated and handled properly. */
{
name: "post-init-system-failure",
key: "post-init-system-failure",
func: function(test) {
var gotReleaseCallback = false;
var gotCloseCallback = false;
function gotAll() {
var all = gotReleaseCallback && gotCloseCallback;
if (all) {
info("Got all expected notifications");
}
return all;
}
function onSuccess(camera, config) {
camera.onClosed = function(reason) {
camera.onClosed = null;
ok(reason === "SystemFailure", "reason is: " + reason);
ok(!gotCloseCallback, "gotCloseCallback was " + gotCloseCallback);
gotCloseCallback = true;
if (gotAll()) {
test.next();
}
camera.release(
function success() {
ok(true, "Got release() success callback");
ok(!gotReleaseCallback, "gotReleaseCallback was " + gotReleaseCallback);
gotReleaseCallback = true;
if (gotAll()) {
test.next();
}
},
function error(e) {
ok(false, "Unexpected release() onError callback: " + e);
test.next();
}
); // release()
} // onClosed
} // onSuccess
function onError(error) {
ok(false, "onError called incorrectly: " + error);
test.next();
}
info("Running test: post-init-system-failure");
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i) {
yield tests[i];
}
}();
CameraTest.begin("hardware", function(test) {
CameraTest.next = function() {
try {
var t = testGenerator.next();
test.set(t.key, t.func.bind(undefined, CameraTest));
} catch(e) {
if (e instanceof StopIteration) {
CameraTest.end();
} else {
throw e;
}
}
};
CameraTest.next();
});
</script>
</body>
</html>

View File

@ -1,16 +1,6 @@
[DEFAULT]
support-files = camera_common.js
[callback/test_camera.html]
[callback/test_camera_2.html]
[callback/test_camera_3.html]
[callback/test_camera_hardware_init_failure.html]
[callback/test_camera_hardware_failures.html]
[callback/test_bug975472.html]
[callback/test_camera_hardware_face_detection.html]
[callback/test_camera_hardware_auto_focus_moving_cb.html]
[callback/test_bug1022766.html]
[callback/test_bug1099390.html]
[test_camera.html]
[test_camera_2.html]
[test_camera_3.html]

View File

@ -38,7 +38,7 @@ var Camera = {
callbackTriggered: false,
checkForDone: function test_checkForDone() {
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
ok(Camera.callbackTriggered, "Async callback triggered");
ok(Camera.callbackTriggered, "Async callback triggered?");
Camera.cameraObj.release();
Camera.cameraObj = null;
CameraTest.end();
@ -50,7 +50,7 @@ var Camera = {
},
failureOne: function test_failureOne(error) {
ok(error.name == "NS_ERROR_IN_PROGRESS", "First call to autoFocus() failed with: "
+ error);
+ error.name);
Camera.firstCallFailed = true;
Camera.checkForDone();
},
@ -62,7 +62,8 @@ var Camera = {
failureTwo: function test_failureTwo(error) {
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
},
callback: function test_callback(focused) {
callback: function test_callback(e) {
Camera.cameraObj.removeEventListener('focus', Camera.callback);
Camera.callbackTriggered = true;
},
@ -75,7 +76,7 @@ var Camera = {
// It doesn't matter if the emulator supports focus or not;
// this is just testing the sequencing.
camera.onAutoFocusCompleted = Camera.callback;
camera.addEventListener('focus', Camera.callback);
camera.autoFocus().then(Camera.successOne, Camera.failureOne);
camera.autoFocus().then(Camera.successTwo, Camera.failureTwo);
};

View File

@ -103,7 +103,7 @@ var Camera = {
},
takePictureSuccess: function taken_foto(blob) {
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
ok("image/" + this._currentTest.fileFormat === blob.type, "Blob Type = " + blob.type);
},
takePictureEvent: function taken_foto_evt(e) {
var blob = e.data;

View File

@ -36,7 +36,7 @@ function end() {
}
function next() {
if (cameraObj) {
cameraObj.release(
cameraObj.release().then(
function success() {
CameraTest.next();
},
@ -345,7 +345,7 @@ var tests = [
run();
});
},
test: function testFakeFocusAreas(cam, cap) {
test: function testFakePictureSizes(cam, cap) {
// validate the capability attribute
ok(cap.pictureSizes.length == 3, "pictureSizes.length = " + cap.pictureSizes.length);
var found = 0;
@ -368,7 +368,7 @@ var tests = [
// settings are applied. Yes--this is an ugly hack.
cam.setConfiguration({ mode: 'video',
recorderProfile: 'weird-unsupported-profile'
}, resolve, resolve);
}).then(resolve, resolve);
});
var sizeGenerator = function() {
var sizes = [ { height: 3264, width: 1836 },

View File

@ -111,17 +111,6 @@ dictionary CameraStartRecordingOptions
boolean autoEnableLowLightTorch = false;
};
callback CameraSetConfigurationCallback = void (CameraConfiguration configuration);
callback CameraAutoFocusCallback = void (boolean focused);
callback CameraTakePictureCallback = void (Blob picture);
callback CameraStartRecordingCallback = void ();
callback CameraShutterCallback = void ();
callback CameraClosedCallback = void (DOMString reason);
callback CameraReleaseCallback = void ();
callback CameraRecorderStateChange = void (DOMString newState);
callback CameraPreviewStateChange = void (DOMString newState);
callback CameraAutoFocusMovingCallback = void (boolean isMoving);
/*
attributes here affect the preview, any pictures taken, and/or
any video recorded by the camera.
@ -231,26 +220,11 @@ interface CameraControl : MediaStream
[Throws]
attribute DOMString isoMode;
/* the function to call on the camera's shutter event, to trigger
a shutter sound and/or a visual shutter indicator. */
attribute CameraShutterCallback? onShutter;
/* the event dispatched on the camera's shutter event, to trigger
a shutter sound and/or a visual shutter indicator.
contains no event-specific data. */
attribute EventHandler onshutter;
/* the function to call when the camera hardware is closed; this may
be due to a system failure, another process taking over the camera,
or a call to release().
The 'reason' will be one of the following string values:
- SystemFailure : the camera subsystem failed and was closed;
- HardwareReleased : a call to release() was successful;
- NotAvailable : the camera hardware is in use by another process.
*/
attribute CameraClosedCallback? onClosed;
attribute EventHandler onshutter;
/* the event dispatched when the camera hardware is closed; this may
be due to a system failure, another process taking over the camera,
@ -262,12 +236,7 @@ interface CameraControl : MediaStream
- HardwareReleased : a call to release() was successful;
- NotAvailable : the camera hardware is in use by another process.
*/
attribute EventHandler onclose;
/* the function to call when the recorder changes state, either because
the recording process encountered an error, or because one of the
recording limits (see CameraStartRecordingOptions) was reached. */
attribute CameraRecorderStateChange? onRecorderStateChange;
attribute EventHandler onclose;
/* the event dispatched when the recorder changes state, either because
the recording process encountered an error, or because one of the
@ -275,18 +244,14 @@ interface CameraControl : MediaStream
event type is CameraStateChangeEvent where:
'newState' is the new recorder state */
attribute EventHandler onrecorderstatechange;
/* the function to call when the viewfinder stops or starts,
useful for synchronizing other UI elements. */
attribute CameraPreviewStateChange? onPreviewStateChange;
attribute EventHandler onrecorderstatechange;
/* the event dispatched when the viewfinder stops or starts,
useful for synchronizing other UI elements.
event type is CameraStateChangeEvent where:
'newState' is the new preview state */
attribute EventHandler onpreviewstatechange;
attribute EventHandler onpreviewstatechange;
/* the size of the picture to be returned by a call to takePicture();
an object with 'height' and 'width' properties that corresponds to
@ -304,7 +269,7 @@ interface CameraControl : MediaStream
'get' the exact value that was previously 'set'. If this setting is
not supported, it is ignored. */
[Throws]
attribute double pictureQuality;
attribute double pictureQuality;
/* the size of the thumbnail to be included in the picture returned
by a call to takePicture(), assuming the chosen fileFormat supports
@ -326,8 +291,7 @@ interface CameraControl : MediaStream
/* tell the camera to attempt to focus the image */
[Throws]
Promise<boolean> autoFocus(optional CameraAutoFocusCallback onSuccess,
optional CameraErrorCallback onError);
Promise<boolean> autoFocus();
/* the event dispatched whenever the focus state changes due to calling
autoFocus or due to continuous autofocus.
@ -344,45 +308,28 @@ interface CameraControl : MediaStream
'focused' if the focus is now set
'focusing' if the focus is moving
'unfocused' if last attempt to focus failed */
attribute EventHandler onfocus;
/* if continuous autofocus is supported and focusMode is set to enable it,
then this function is called whenever the camera decides to start and
stop moving the focus position; it can be used to update a UI element to
indicate that the camera is still trying to focus, or has finished. Some
platforms do not support this event, in which case the callback is never
invoked. */
[Pref="camera.control.autofocus_moving_callback.enabled"]
attribute CameraAutoFocusMovingCallback? onAutoFocusMoving;
/* this function is called whenever auto focus completes, due to continuous
autofocus or a solicited auto focus. */
attribute CameraAutoFocusCallback? onAutoFocusCompleted;
attribute EventHandler onfocus;
/* capture an image and return it as a blob to the 'onSuccess' callback;
if the camera supports it, this may be invoked while the camera is
already recording video.
invoking this function will stop the preview stream, which must be
manually restarted (e.g. by calling .play() on it). */
manually restarted by calling resumePreview(). */
[Throws]
Promise<Blob> takePicture(optional CameraPictureOptions aOptions,
optional CameraTakePictureCallback onSuccess,
optional CameraErrorCallback onError);
Promise<Blob> takePicture(optional CameraPictureOptions options);
/* the event dispatched when a picture is successfully taken; it is of the
type BlobEvent, where the data attribute contains the picture. */
attribute EventHandler onpicture;
attribute EventHandler onpicture;
/* start recording video; 'aOptions' is a CameraStartRecordingOptions object.
/* start recording video; 'options' is a CameraStartRecordingOptions object.
If the success/error callbacks are not used, one may determine success by
waiting for the recorderstatechange event. */
[Throws]
Promise<void> startRecording(CameraStartRecordingOptions aOptions,
Promise<void> startRecording(CameraStartRecordingOptions options,
DeviceStorage storageArea,
DOMString filename,
optional CameraStartRecordingCallback onSuccess,
optional CameraErrorCallback onError);
DOMString filename);
/* stop precording video. */
[Throws]
@ -397,27 +344,14 @@ interface CameraControl : MediaStream
probably call this whenever the camera is not longer in the foreground
(depending on your usage model).
the callbacks are optional, unless you really need to know when
the hardware is ultimately released.
once this is called, the camera control object is to be considered
defunct; a new instance will need to be created to access the camera. */
[Throws]
Promise<void> release(optional CameraReleaseCallback onSuccess,
optional CameraErrorCallback onError);
Promise<void> release();
/* changes the camera configuration on the fly;
'configuration' is of type CameraConfiguration.
XXXmikeh the 'configuration' argument needs to be optional, else
the WebIDL compiler throws: "WebIDL.WebIDLError: error: Dictionary
argument or union argument containing a dictionary not followed by
a required argument must be optional"
*/
/* changes the camera configuration on the fly. */
[Throws]
Promise<CameraConfiguration> setConfiguration(optional CameraConfiguration configuration,
optional CameraSetConfigurationCallback onSuccess,
optional CameraErrorCallback onError);
Promise<CameraConfiguration> setConfiguration(optional CameraConfiguration configuration);
/* the event dispatched when the camera is successfully configured.
@ -524,12 +458,7 @@ partial interface CameraControl
[Throws, Pref="camera.control.face_detection.enabled"]
void stopFaceDetection();
/* Callback for faces detected in the preview frame. If no faces are
detected, the callback is invoked with an empty sequence. */
[Pref="camera.control.face_detection.enabled"]
attribute CameraFaceDetectionCallback? onFacesDetected;
/* CameraFacesDetectedEvent */
[Pref="camera.control.face_detection.enabled"]
attribute EventHandler onfacesdetected;
attribute EventHandler onfacesdetected;
};

View File

@ -24,11 +24,6 @@ dictionary CameraConfiguration
// CameraControl.capabilities.recorderProfiles
};
callback CameraErrorCallback = void (DOMString error);
callback GetCameraCallback = void (CameraControl camera,
CameraConfiguration configuration);
[Func="nsDOMCameraManager::HasSupport"]
interface CameraManager
{
@ -37,9 +32,7 @@ interface CameraManager
*/
[Throws]
Promise<CameraGetPromiseData> getCamera(DOMString camera,
optional CameraConfiguration initialConfiguration,
optional GetCameraCallback callback,
optional CameraErrorCallback errorCallback);
optional CameraConfiguration initialConfiguration);
/* return an array of camera identifiers, e.g.
[ "front", "back" ]

View File

@ -1,247 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_InputBlockState_h
#define mozilla_layers_InputBlockState_h
#include "nsTArray.h" // for nsTArray
#include "InputData.h" // for MultiTouchInput
#include "nsAutoPtr.h"
namespace mozilla {
namespace layers {
class AsyncPanZoomController;
class OverscrollHandoffChain;
class CancelableBlockState;
class TouchBlockState;
class WheelBlockState;
/**
* A base class that stores state common to various input blocks.
* Currently, it just stores the overscroll handoff chain.
*/
class InputBlockState
{
public:
static const uint64_t NO_BLOCK_ID = 0;
explicit InputBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed);
virtual ~InputBlockState()
{}
bool SetConfirmedTargetApzc(const nsRefPtr<AsyncPanZoomController>& aTargetApzc);
const nsRefPtr<AsyncPanZoomController>& GetTargetApzc() const;
const nsRefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
uint64_t GetBlockId() const;
bool IsTargetConfirmed() const;
private:
nsRefPtr<AsyncPanZoomController> mTargetApzc;
nsRefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;
bool mTargetConfirmed;
const uint64_t mBlockId;
};
/**
* This class represents a set of events that can be cancelled by web content
* via event listeners.
*
* Each cancelable input block can be cancelled by web content, and
* this information is stored in the mPreventDefault flag. Because web
* content runs on the Gecko main thread, we cannot always wait for web content's
* response. Instead, there is a timeout that sets this flag in the case
* where web content doesn't respond in time. The mContentResponded
* and mContentResponseTimerExpired flags indicate which of these scenarios
* occurred.
*/
class CancelableBlockState : public InputBlockState
{
public:
CancelableBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed);
virtual TouchBlockState *AsTouchBlock() {
return nullptr;
}
/**
* Record whether or not content cancelled this block of events.
* @param aPreventDefault true iff the block is cancelled.
* @return false if this block has already received a response from
* web content, true if not.
*/
bool SetContentResponse(bool aPreventDefault);
/**
* Record that content didn't respond in time.
* @return false if this block already timed out, true if not.
*/
bool TimeoutContentResponse();
/**
* @return true iff web content cancelled this block of events.
*/
bool IsDefaultPrevented() const;
/**
* @return true iff this block has received all the information needed
* to properly dispatch the events in the block.
*/
virtual bool IsReadyForHandling() const;
<<<<<<< HEAD
private:
=======
/**
* Returns whether or not this block has pending events.
*/
virtual bool HasEvents() const = 0;
/**
* Throw away all the events in this input block.
*/
virtual void DropEvents() = 0;
/**
* Process all events given an apzc, leaving ths block depleted.
*/
virtual void HandleEvents(const nsRefPtr<AsyncPanZoomController>& aTarget) = 0;
/**
* Return true if this input block must stay active if it would otherwise
* be removed as the last item in the pending queue.
*/
virtual bool MustStayActive() = 0;
/**
* Return a descriptive name for the block kind.
*/
virtual const char* Type() = 0;
private:
>>>>>>> 80325be... Refactor InputQueue to hold more than touch events. (bug 1013432 part 2, r=kats)
bool mPreventDefault;
bool mContentResponded;
bool mContentResponseTimerExpired;
};
/**
* This class represents a single touch block. A touch block is
* a set of touch events that can be cancelled by web content via
* touch event listeners.
*
* Every touch-start event creates a new touch block. In this case, the
* touch block consists of the touch-start, followed by all touch events
* up to but not including the next touch-start (except in the case where
* a long-tap happens, see below). Note that in particular we cannot know
* when a touch block ends until the next one is started. Most touch
* blocks are created by receipt of a touch-start event.
*
* Every long-tap event also creates a new touch block, since it can also
* be consumed by web content. In this case, when the long-tap event is
* dispatched to web content, a new touch block is started to hold the remaining
* touch events, up to but not including the next touch start (or long-tap).
*
* Additionally, if touch-action is enabled, each touch block should
* have a set of allowed touch behavior flags; one for each touch point.
* This also requires running code on the Gecko main thread, and so may
* be populated with some latency. The mAllowedTouchBehaviorSet and
* mAllowedTouchBehaviors variables track this information.
*/
class TouchBlockState : public CancelableBlockState
{
public:
typedef uint32_t TouchBehaviorFlags;
explicit TouchBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
bool aTargetConfirmed);
TouchBlockState *AsTouchBlock() MOZ_OVERRIDE {
return this;
}
/**
* Set the allowed touch behavior flags for this block.
* @return false if this block already has these flags set, true if not.
*/
bool SetAllowedTouchBehaviors(const nsTArray<TouchBehaviorFlags>& aBehaviors);
/**
* Copy the allowed touch behavior flags from another block.
* @return false if this block already has these flags set, true if not.
*/
bool CopyAllowedTouchBehaviorsFrom(const TouchBlockState& aOther);
/**
* @return true iff this block has received all the information needed
* to properly dispatch the events in the block.
*/
bool IsReadyForHandling() const MOZ_OVERRIDE;
/**
* Set a flag that disables setting the single-tap flag on this block.
*/
void DisallowSingleTap();
/**
* Set a flag that indicates that this touch block triggered a single tap event.
* @return true iff DisallowSingleTap was not previously called.
*/
bool SetSingleTapOccurred();
/**
* @return true iff SetSingleTapOccurred was previously called on this block.
*/
bool SingleTapOccurred() const;
/**
* Add a new touch event to the queue of events in this input block.
*/
void AddEvent(const MultiTouchInput& aEvent);
/**
* @return false iff touch-action is enabled and the allowed touch behaviors for
* this touch block do not allow pinch-zooming.
*/
bool TouchActionAllowsPinchZoom() const;
/**
* @return false iff touch-action is enabled and the allowed touch behaviors for
* this touch block do not allow double-tap zooming.
*/
bool TouchActionAllowsDoubleTapZoom() const;
/**
* @return false iff touch-action is enabled and the allowed touch behaviors for
* the first touch point do not allow panning in the specified direction(s).
*/
bool TouchActionAllowsPanningX() const;
bool TouchActionAllowsPanningY() const;
bool TouchActionAllowsPanningXY() const;
bool HasEvents() const MOZ_OVERRIDE;
void DropEvents() MOZ_OVERRIDE;
void HandleEvents(const nsRefPtr<AsyncPanZoomController>& aTarget) MOZ_OVERRIDE;
bool MustStayActive() MOZ_OVERRIDE;
const char* Type() MOZ_OVERRIDE;
private:
/**
* @return the first event in the queue. The event is removed from the queue
* before it is returned.
*/
MultiTouchInput RemoveFirstEvent();
private:
nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
bool mAllowedTouchBehaviorSet;
bool mSingleTapDisallowed;
bool mSingleTapOccurred;
nsTArray<MultiTouchInput> mEvents;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_InputBlockState_h

View File

@ -4388,7 +4388,6 @@ pref("beacon.enabled", true);
#endif
// Camera prefs
pref("camera.control.autofocus_moving_callback.enabled", true);
pref("camera.control.face_detection.enabled", true);
// Fetch API.