1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "base/basictypes.h"
8 #include "nsDOMClassInfo.h"
10 #include "DOMCameraControl.h"
11 #include "DOMCameraCapabilities.h"
12 #include "CameraCommon.h"
14 using namespace mozilla
;
16 DOMCI_DATA(CameraCapabilities
, nsICameraCapabilities
)
18 NS_IMPL_CYCLE_COLLECTION_0(DOMCameraCapabilities
)
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMCameraCapabilities
)
21 NS_INTERFACE_MAP_ENTRY(nsISupports
)
22 NS_INTERFACE_MAP_ENTRY(nsICameraCapabilities
)
23 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CameraCapabilities
)
26 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMCameraCapabilities
)
27 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMCameraCapabilities
)
30 ParseZoomRatioItemAndAdd(JSContext
* aCx
, JSObject
* aArray
, uint32_t aIndex
, const char* aStart
, char** aEnd
)
33 // make 'aEnd' follow the same semantics as strchr().
38 * The by-100 divisor is Gonk-specific. For now, assume other platforms
39 * return actual fractoinal multipliers.
41 double d
= strtod(aStart
, aEnd
);
46 jsval v
= JS_NumberValue(d
);
48 if (!JS_SetElement(aCx
, aArray
, aIndex
, &v
)) {
49 return NS_ERROR_FAILURE
;
56 ParseStringItemAndAdd(JSContext
* aCx
, JSObject
* aArray
, uint32_t aIndex
, const char* aStart
, char** aEnd
)
61 s
= JS_NewStringCopyN(aCx
, aStart
, *aEnd
- aStart
);
63 s
= JS_NewStringCopyZ(aCx
, aStart
);
66 return NS_ERROR_OUT_OF_MEMORY
;
69 jsval v
= STRING_TO_JSVAL(s
);
70 if (!JS_SetElement(aCx
, aArray
, aIndex
, &v
)) {
71 return NS_ERROR_FAILURE
;
78 ParseDimensionItemAndAdd(JSContext
* aCx
, JSObject
* aArray
, uint32_t aIndex
, const char* aStart
, char** aEnd
)
83 // make 'aEnd' follow the same semantics as strchr().
87 jsval w
= INT_TO_JSVAL(strtol(aStart
, &x
, 10));
88 jsval h
= INT_TO_JSVAL(strtol(x
+ 1, aEnd
, 10));
90 JSObject
* o
= JS_NewObject(aCx
, nullptr, nullptr, nullptr);
92 return NS_ERROR_OUT_OF_MEMORY
;
95 if (!JS_SetProperty(aCx
, o
, "width", &w
)) {
96 return NS_ERROR_FAILURE
;
98 if (!JS_SetProperty(aCx
, o
, "height", &h
)) {
99 return NS_ERROR_FAILURE
;
102 jsval v
= OBJECT_TO_JSVAL(o
);
103 if (!JS_SetElement(aCx
, aArray
, aIndex
, &v
)) {
104 return NS_ERROR_FAILURE
;
111 DOMCameraCapabilities::ParameterListToNewArray(JSContext
* aCx
, JSObject
** aArray
, uint32_t aKey
, ParseItemAndAddFunc aParseItemAndAdd
)
113 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
115 const char* value
= mCamera
->GetParameterConstChar(aKey
);
117 // in case we get nonsense data back
122 *aArray
= JS_NewArrayObject(aCx
, 0, nullptr);
124 return NS_ERROR_OUT_OF_MEMORY
;
127 const char* p
= value
;
134 * In C's string.h, strchr() is declared as returning 'char*'; in C++'s
135 * cstring, it is declared as returning 'const char*', _except_ in MSVC,
136 * where the C version is declared to return const like the C++ version.
138 * Unfortunately, for both cases, strtod() and strtol() take a 'char**' as
139 * the end-of-conversion pointer, so we need to cast away strchr()'s
140 * const-ness here to make the MSVC build everything happy.
142 q
= const_cast<char*>(strchr(p
, ','));
143 if (q
!= p
) { // skip consecutive delimiters, just in case
144 rv
= aParseItemAndAdd(aCx
, *aArray
, index
, p
, &q
);
145 NS_ENSURE_SUCCESS(rv
, rv
);
154 return JS_FreezeObject(aCx
, *aArray
) ? NS_OK
: NS_ERROR_FAILURE
;
158 DOMCameraCapabilities::StringListToNewObject(JSContext
* aCx
, JS::Value
* aArray
, uint32_t aKey
)
162 nsresult rv
= ParameterListToNewArray(aCx
, &array
, aKey
, ParseStringItemAndAdd
);
163 NS_ENSURE_SUCCESS(rv
, rv
);
165 *aArray
= OBJECT_TO_JSVAL(array
);
170 DOMCameraCapabilities::DimensionListToNewObject(JSContext
* aCx
, JS::Value
* aArray
, uint32_t aKey
)
175 rv
= ParameterListToNewArray(aCx
, &array
, aKey
, ParseDimensionItemAndAdd
);
176 NS_ENSURE_SUCCESS(rv
, rv
);
178 *aArray
= OBJECT_TO_JSVAL(array
);
182 /* readonly attribute jsval previewSizes; */
184 DOMCameraCapabilities::GetPreviewSizes(JSContext
* cx
, JS::Value
* aPreviewSizes
)
186 return DimensionListToNewObject(cx
, aPreviewSizes
, CAMERA_PARAM_SUPPORTED_PREVIEWSIZES
);
189 /* readonly attribute jsval pictureSizes; */
191 DOMCameraCapabilities::GetPictureSizes(JSContext
* cx
, JS::Value
* aPictureSizes
)
193 return DimensionListToNewObject(cx
, aPictureSizes
, CAMERA_PARAM_SUPPORTED_PICTURESIZES
);
196 /* readonly attribute jsval fileFormats; */
198 DOMCameraCapabilities::GetFileFormats(JSContext
* cx
, JS::Value
* aFileFormats
)
200 return StringListToNewObject(cx
, aFileFormats
, CAMERA_PARAM_SUPPORTED_PICTUREFORMATS
);
203 /* readonly attribute jsval whiteBalanceModes; */
205 DOMCameraCapabilities::GetWhiteBalanceModes(JSContext
* cx
, JS::Value
* aWhiteBalanceModes
)
207 return StringListToNewObject(cx
, aWhiteBalanceModes
, CAMERA_PARAM_SUPPORTED_WHITEBALANCES
);
210 /* readonly attribute jsval sceneModes; */
212 DOMCameraCapabilities::GetSceneModes(JSContext
* cx
, JS::Value
* aSceneModes
)
214 return StringListToNewObject(cx
, aSceneModes
, CAMERA_PARAM_SUPPORTED_SCENEMODES
);
217 /* readonly attribute jsval effects; */
219 DOMCameraCapabilities::GetEffects(JSContext
* cx
, JS::Value
* aEffects
)
221 return StringListToNewObject(cx
, aEffects
, CAMERA_PARAM_SUPPORTED_EFFECTS
);
224 /* readonly attribute jsval flashModes; */
226 DOMCameraCapabilities::GetFlashModes(JSContext
* cx
, JS::Value
* aFlashModes
)
228 return StringListToNewObject(cx
, aFlashModes
, CAMERA_PARAM_SUPPORTED_FLASHMODES
);
231 /* readonly attribute jsval focusModes; */
233 DOMCameraCapabilities::GetFocusModes(JSContext
* cx
, JS::Value
* aFocusModes
)
235 return StringListToNewObject(cx
, aFocusModes
, CAMERA_PARAM_SUPPORTED_FOCUSMODES
);
238 /* readonly attribute long maxFocusAreas; */
240 DOMCameraCapabilities::GetMaxFocusAreas(JSContext
* cx
, int32_t* aMaxFocusAreas
)
242 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
244 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS
);
246 // in case we get nonsense data back
251 *aMaxFocusAreas
= atoi(value
);
255 /* readonly attribute double minExposureCompensation; */
257 DOMCameraCapabilities::GetMinExposureCompensation(JSContext
* cx
, double* aMinExposureCompensation
)
259 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
261 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION
);
263 // in case we get nonsense data back
264 *aMinExposureCompensation
= 0;
268 *aMinExposureCompensation
= atof(value
);
272 /* readonly attribute double maxExposureCompensation; */
274 DOMCameraCapabilities::GetMaxExposureCompensation(JSContext
* cx
, double* aMaxExposureCompensation
)
276 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
278 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION
);
280 // in case we get nonsense data back
281 *aMaxExposureCompensation
= 0;
285 *aMaxExposureCompensation
= atof(value
);
289 /* readonly attribute double stepExposureCompensation; */
291 DOMCameraCapabilities::GetStepExposureCompensation(JSContext
* cx
, double* aStepExposureCompensation
)
293 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
295 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP
);
297 // in case we get nonsense data back
298 *aStepExposureCompensation
= 0;
302 *aStepExposureCompensation
= atof(value
);
306 /* readonly attribute long maxMeteringAreas; */
308 DOMCameraCapabilities::GetMaxMeteringAreas(JSContext
* cx
, int32_t* aMaxMeteringAreas
)
310 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
312 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS
);
314 // in case we get nonsense data back
315 *aMaxMeteringAreas
= 0;
319 *aMaxMeteringAreas
= atoi(value
);
323 /* readonly attribute jsval zoomRatios; */
325 DOMCameraCapabilities::GetZoomRatios(JSContext
* cx
, JS::Value
* aZoomRatios
)
327 NS_ENSURE_TRUE(mCamera
, NS_ERROR_NOT_AVAILABLE
);
329 const char* value
= mCamera
->GetParameterConstChar(CAMERA_PARAM_SUPPORTED_ZOOM
);
330 if (!value
|| strcmp(value
, "true") != 0) {
331 // if zoom is not supported, return a null object
332 *aZoomRatios
= JSVAL_NULL
;
338 nsresult rv
= ParameterListToNewArray(cx
, &array
, CAMERA_PARAM_SUPPORTED_ZOOMRATIOS
, ParseZoomRatioItemAndAdd
);
339 NS_ENSURE_SUCCESS(rv
, rv
);
341 *aZoomRatios
= OBJECT_TO_JSVAL(array
);
345 /* readonly attribute jsval videoSizes; */
347 DOMCameraCapabilities::GetVideoSizes(JSContext
* cx
, JS::Value
* aVideoSizes
)
349 return DimensionListToNewObject(cx
, aVideoSizes
, CAMERA_PARAM_SUPPORTED_VIDEOSIZES
);