michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "DOMCameraCapabilities.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsContentUtils.h" michael@0: #include "mozilla/dom/CameraManagerBinding.h" michael@0: #include "mozilla/dom/CameraCapabilitiesBinding.h" michael@0: #include "Navigator.h" michael@0: #include "CameraCommon.h" michael@0: #include "ICameraControl.h" michael@0: #include "CameraRecorderProfiles.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_CLASS(CameraCapabilities) michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CameraCapabilities) michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow) michael@0: tmp->mRecorderProfiles = JS::UndefinedValue(); michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER michael@0: NS_IMPL_CYCLE_COLLECTION_UNLINK_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CameraCapabilities) michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow) michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS michael@0: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CameraCapabilities) michael@0: NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mRecorderProfiles) michael@0: NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER michael@0: NS_IMPL_CYCLE_COLLECTION_TRACE_END michael@0: michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraCapabilities) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraCapabilities) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraCapabilities) michael@0: NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: /* static */ michael@0: bool michael@0: CameraCapabilities::HasSupport(JSContext* aCx, JSObject* aGlobal) michael@0: { michael@0: return Navigator::HasCameraSupport(aCx, aGlobal); michael@0: } michael@0: michael@0: CameraCapabilities::CameraCapabilities(nsPIDOMWindow* aWindow) michael@0: : mRecorderProfiles(JS::UndefinedValue()) michael@0: , mWindow(aWindow) michael@0: { michael@0: DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); michael@0: MOZ_COUNT_CTOR(CameraCapabilities); michael@0: mozilla::HoldJSObjects(this); michael@0: SetIsDOMBinding(); michael@0: } michael@0: michael@0: CameraCapabilities::~CameraCapabilities() michael@0: { michael@0: DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this); michael@0: mRecorderProfiles = JS::UndefinedValue(); michael@0: mozilla::DropJSObjects(this); michael@0: MOZ_COUNT_DTOR(CameraCapabilities); michael@0: } michael@0: michael@0: JSObject* michael@0: CameraCapabilities::WrapObject(JSContext* aCx) michael@0: { michael@0: return CameraCapabilitiesBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: #define LOG_IF_ERROR(rv, param) \ michael@0: do { \ michael@0: if (NS_FAILED(rv)) { \ michael@0: DOM_CAMERA_LOGW("Error %x trying to get " #param "\n", \ michael@0: (rv)); \ michael@0: } \ michael@0: } while(0) michael@0: michael@0: nsresult michael@0: CameraCapabilities::TranslateToDictionary(ICameraControl* aCameraControl, michael@0: uint32_t aKey, nsTArray& aSizes) michael@0: { michael@0: nsresult rv; michael@0: nsTArray sizes; michael@0: michael@0: rv = aCameraControl->Get(aKey, sizes); michael@0: if (NS_FAILED(rv)) { michael@0: return rv; michael@0: } michael@0: michael@0: aSizes.Clear(); michael@0: aSizes.SetCapacity(sizes.Length()); michael@0: for (uint32_t i = 0; i < sizes.Length(); ++i) { michael@0: CameraSize* s = aSizes.AppendElement(); michael@0: s->mWidth = sizes[i].width; michael@0: s->mHeight = sizes[i].height; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: CameraCapabilities::Populate(ICameraControl* aCameraControl) michael@0: { michael@0: NS_ENSURE_TRUE(aCameraControl, NS_ERROR_INVALID_ARG); michael@0: michael@0: nsresult rv; michael@0: michael@0: rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, mPreviewSizes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES); michael@0: michael@0: rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_PICTURESIZES, mPictureSizes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTURESIZES); michael@0: michael@0: rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES, mThumbnailSizes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES); michael@0: michael@0: rv = TranslateToDictionary(aCameraControl, CAMERA_PARAM_SUPPORTED_VIDEOSIZES, mVideoSizes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_VIDEOSIZES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_PICTUREFORMATS, mFileFormats); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_WHITEBALANCES, mWhiteBalanceModes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_WHITEBALANCES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_SCENEMODES, mSceneModes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_SCENEMODES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_EFFECTS, mEffects); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EFFECTS); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_FLASHMODES, mFlashModes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FLASHMODES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_FOCUSMODES, mFocusModes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_FOCUSMODES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_ISOMODES, mIsoModes); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ISOMODES); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_ZOOMRATIOS, mZoomRatios); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS); michael@0: michael@0: int32_t areas; michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS, areas); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS); michael@0: mMaxFocusAreas = areas < 0 ? 0 : areas; michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS, areas); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS); michael@0: mMaxMeteringAreas = areas < 0 ? 0 : areas; michael@0: michael@0: int32_t faces; michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES, faces); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES); michael@0: mMaxDetectedFaces = faces < 0 ? 0 : faces; michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION, mMinExposureCompensation); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION, mMaxExposureCompensation); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION); michael@0: michael@0: rv = aCameraControl->Get(CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP, mExposureCompensationStep); michael@0: LOG_IF_ERROR(rv, CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP); michael@0: michael@0: mRecorderProfileManager = aCameraControl->GetRecorderProfileManager(); michael@0: if (!mRecorderProfileManager) { michael@0: DOM_CAMERA_LOGW("Unable to get recorder profile manager\n"); michael@0: } else { michael@0: AutoJSContext js; michael@0: michael@0: JS::Rooted o(js); michael@0: nsresult rv = mRecorderProfileManager->GetJsObject(js, o.address()); michael@0: if (NS_FAILED(rv)) { michael@0: DOM_CAMERA_LOGE("Failed to JS-objectify profile manager (%d)\n", rv); michael@0: return rv; michael@0: } michael@0: michael@0: mRecorderProfiles = JS::ObjectValue(*o); michael@0: } michael@0: michael@0: // For now, always return success, since the presence or absence of capabilities michael@0: // indicates whether or not they are supported. michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetPreviewSizes(nsTArray& retval) const michael@0: { michael@0: retval = mPreviewSizes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetPictureSizes(nsTArray& retval) const michael@0: { michael@0: retval = mPictureSizes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetThumbnailSizes(nsTArray& retval) const michael@0: { michael@0: retval = mThumbnailSizes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetVideoSizes(nsTArray& retval) const michael@0: { michael@0: retval = mVideoSizes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetFileFormats(nsTArray& retval) const michael@0: { michael@0: retval = mFileFormats; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetWhiteBalanceModes(nsTArray& retval) const michael@0: { michael@0: retval = mWhiteBalanceModes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetSceneModes(nsTArray& retval) const michael@0: { michael@0: retval = mSceneModes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetEffects(nsTArray& retval) const michael@0: { michael@0: retval = mEffects; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetFlashModes(nsTArray& retval) const michael@0: { michael@0: retval = mFlashModes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetFocusModes(nsTArray& retval) const michael@0: { michael@0: retval = mFocusModes; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetZoomRatios(nsTArray& retval) const michael@0: { michael@0: retval = mZoomRatios; michael@0: } michael@0: michael@0: uint32_t michael@0: CameraCapabilities::MaxFocusAreas() const michael@0: { michael@0: return mMaxFocusAreas; michael@0: } michael@0: michael@0: uint32_t michael@0: CameraCapabilities::MaxMeteringAreas() const michael@0: { michael@0: return mMaxMeteringAreas; michael@0: } michael@0: michael@0: uint32_t michael@0: CameraCapabilities::MaxDetectedFaces() const michael@0: { michael@0: return mMaxDetectedFaces; michael@0: } michael@0: michael@0: double michael@0: CameraCapabilities::MinExposureCompensation() const michael@0: { michael@0: return mMinExposureCompensation; michael@0: } michael@0: michael@0: double michael@0: CameraCapabilities::MaxExposureCompensation() const michael@0: { michael@0: return mMaxExposureCompensation; michael@0: } michael@0: michael@0: double michael@0: CameraCapabilities::ExposureCompensationStep() const michael@0: { michael@0: return mExposureCompensationStep; michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetRecorderProfiles(JSContext* aCx, michael@0: JS::MutableHandle aRetval) const michael@0: { michael@0: JS::ExposeValueToActiveJS(mRecorderProfiles); michael@0: aRetval.set(mRecorderProfiles); michael@0: } michael@0: michael@0: void michael@0: CameraCapabilities::GetIsoModes(nsTArray& retval) const michael@0: { michael@0: retval = mIsoModes; michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla