mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1107683 - remove method callbacks from CameraControl, r=aosmond,bz
This commit is contained in:
parent
2fcdb603d3
commit
b3d455fadf
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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]
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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" ]
|
||||
|
@ -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
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user