2 * Copyright (C) 2013-2014 Mozilla Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "GonkCameraParameters.h"
18 #include "camera/CameraParameters.h"
19 #include "CameraPreferences.h"
20 #include "ICameraControl.h"
21 #include "CameraCommon.h"
22 #include "mozilla/Hal.h"
24 using namespace mozilla
;
25 using namespace android
;
28 GonkCameraParameters::IsLowMemoryPlatform()
30 bool testIsLowMem
= false;
31 CameraPreferences::GetPref("camera.control.test.is_low_memory", testIsLowMem
);
33 NS_WARNING("Forcing low-memory platform camera preferences");
37 uint32_t lowMemoryThresholdBytes
= 0;
38 CameraPreferences::GetPref("camera.control.low_memory_thresholdMB",
39 lowMemoryThresholdBytes
);
40 lowMemoryThresholdBytes
*= 1024 * 1024;
41 if (lowMemoryThresholdBytes
) {
42 uint32_t totalMemoryBytes
= hal::GetTotalSystemMemory();
43 if (totalMemoryBytes
< lowMemoryThresholdBytes
) {
44 DOM_CAMERA_LOGI("Low-memory platform with %d bytes of RAM (threshold: <%d bytes)\n",
45 totalMemoryBytes
, lowMemoryThresholdBytes
);
53 /* static */ const char*
54 GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey
)
57 case CAMERA_PARAM_PREVIEWSIZE
:
58 return KEY_PREVIEW_SIZE
;
59 case CAMERA_PARAM_PREVIEWFORMAT
:
60 return KEY_PREVIEW_FORMAT
;
61 case CAMERA_PARAM_PREVIEWFRAMERATE
:
62 return KEY_PREVIEW_FRAME_RATE
;
63 case CAMERA_PARAM_EFFECT
:
65 case CAMERA_PARAM_WHITEBALANCE
:
66 return KEY_WHITE_BALANCE
;
67 case CAMERA_PARAM_SCENEMODE
:
68 return KEY_SCENE_MODE
;
69 case CAMERA_PARAM_FLASHMODE
:
70 return KEY_FLASH_MODE
;
71 case CAMERA_PARAM_FOCUSMODE
:
72 return KEY_FOCUS_MODE
;
73 case CAMERA_PARAM_ZOOM
:
75 case CAMERA_PARAM_METERINGAREAS
:
76 return KEY_METERING_AREAS
;
77 case CAMERA_PARAM_FOCUSAREAS
:
78 return KEY_FOCUS_AREAS
;
79 case CAMERA_PARAM_FOCALLENGTH
:
80 return KEY_FOCAL_LENGTH
;
81 case CAMERA_PARAM_FOCUSDISTANCENEAR
:
82 return KEY_FOCUS_DISTANCES
;
83 case CAMERA_PARAM_FOCUSDISTANCEOPTIMUM
:
84 return KEY_FOCUS_DISTANCES
;
85 case CAMERA_PARAM_FOCUSDISTANCEFAR
:
86 return KEY_FOCUS_DISTANCES
;
87 case CAMERA_PARAM_EXPOSURECOMPENSATION
:
88 return KEY_EXPOSURE_COMPENSATION
;
89 case CAMERA_PARAM_THUMBNAILQUALITY
:
90 return KEY_JPEG_THUMBNAIL_QUALITY
;
91 case CAMERA_PARAM_PICTURE_SIZE
:
92 return KEY_PICTURE_SIZE
;
93 case CAMERA_PARAM_PICTURE_FILEFORMAT
:
94 return KEY_PICTURE_FORMAT
;
95 case CAMERA_PARAM_PICTURE_ROTATION
:
97 case CAMERA_PARAM_PICTURE_DATETIME
:
98 // Not every platform defines a KEY_EXIF_DATETIME;
99 // for those that don't, we use the raw string key, and if the platform
100 // doesn't support it, it will be ignored.
103 return "exif-datetime";
104 case CAMERA_PARAM_VIDEOSIZE
:
105 return KEY_VIDEO_SIZE
;
106 case CAMERA_PARAM_ISOMODE
:
107 // Not every platform defines KEY_ISO_MODE;
108 // for those that don't, we use the raw string key.
110 case CAMERA_PARAM_LUMINANCE
:
111 return "luminance-condition";
112 case CAMERA_PARAM_SCENEMODE_HDR_RETURNNORMALPICTURE
:
113 // Not every platform defines KEY_QC_HDR_NEED_1X;
114 // for those that don't, we use the raw string key.
115 return "hdr-need-1x";
116 case CAMERA_PARAM_RECORDINGHINT
:
117 return KEY_RECORDING_HINT
;
118 case CAMERA_PARAM_PICTURE_QUALITY
:
119 return KEY_JPEG_QUALITY
;
121 case CAMERA_PARAM_SUPPORTED_PREVIEWSIZES
:
122 return KEY_SUPPORTED_PREVIEW_SIZES
;
123 case CAMERA_PARAM_SUPPORTED_PICTURESIZES
:
124 return KEY_SUPPORTED_PICTURE_SIZES
;
125 case CAMERA_PARAM_SUPPORTED_VIDEOSIZES
:
126 return KEY_SUPPORTED_VIDEO_SIZES
;
127 case CAMERA_PARAM_SUPPORTED_PICTUREFORMATS
:
128 return KEY_SUPPORTED_PICTURE_FORMATS
;
129 case CAMERA_PARAM_SUPPORTED_WHITEBALANCES
:
130 return KEY_SUPPORTED_WHITE_BALANCE
;
131 case CAMERA_PARAM_SUPPORTED_SCENEMODES
:
132 return KEY_SUPPORTED_SCENE_MODES
;
133 case CAMERA_PARAM_SUPPORTED_EFFECTS
:
134 return KEY_SUPPORTED_EFFECTS
;
135 case CAMERA_PARAM_SUPPORTED_FLASHMODES
:
136 return KEY_SUPPORTED_FLASH_MODES
;
137 case CAMERA_PARAM_SUPPORTED_FOCUSMODES
:
138 return KEY_SUPPORTED_FOCUS_MODES
;
139 case CAMERA_PARAM_SUPPORTED_MAXFOCUSAREAS
:
140 return KEY_MAX_NUM_FOCUS_AREAS
;
141 case CAMERA_PARAM_SUPPORTED_MAXMETERINGAREAS
:
142 return KEY_MAX_NUM_METERING_AREAS
;
143 case CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION
:
144 return KEY_MIN_EXPOSURE_COMPENSATION
;
145 case CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION
:
146 return KEY_MAX_EXPOSURE_COMPENSATION
;
147 case CAMERA_PARAM_SUPPORTED_EXPOSURECOMPENSATIONSTEP
:
148 return KEY_EXPOSURE_COMPENSATION_STEP
;
149 case CAMERA_PARAM_SUPPORTED_ZOOM
:
150 return KEY_ZOOM_SUPPORTED
;
151 case CAMERA_PARAM_SUPPORTED_ZOOMRATIOS
:
152 return KEY_ZOOM_RATIOS
;
153 case CAMERA_PARAM_SUPPORTED_MAXDETECTEDFACES
:
154 return KEY_MAX_NUM_DETECTED_FACES_HW
;
155 case CAMERA_PARAM_SUPPORTED_JPEG_THUMBNAIL_SIZES
:
156 return KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES
;
157 case CAMERA_PARAM_SUPPORTED_ISOMODES
:
158 // Not every platform defines KEY_SUPPORTED_ISO_MODES;
159 // for those that don't, we use the raw string key.
162 DOM_CAMERA_LOGE("Unhandled camera parameter value %u\n", aKey
);
167 GonkCameraParameters::GonkCameraParameters()
168 : mLock(PR_NewRWLock(PR_RWLOCK_RANK_NONE
, "GonkCameraParameters.Lock"))
170 , mInitialized(false)
171 , mExposureCompensationStep(0.0)
173 MOZ_COUNT_CTOR(GonkCameraParameters
);
175 MOZ_CRASH("Out of memory getting new PRRWLock");
179 GonkCameraParameters::~GonkCameraParameters()
181 MOZ_COUNT_DTOR(GonkCameraParameters
);
183 MOZ_ASSERT(mLock
, "mLock missing in ~GonkCameraParameters()");
185 PR_DestroyRWLock(mLock
);
191 GonkCameraParameters::MapIsoToGonk(const nsAString
& aIso
, nsACString
& aIsoOut
)
194 if (mIsoModeMap
.Get(aIso
, &s
)) {
196 DOM_CAMERA_LOGE("ISO mode '%s' maps to null Gonk ISO value\n",
197 NS_LossyConvertUTF16toASCII(aIso
).get());
198 return NS_ERROR_FAILURE
;
205 return NS_ERROR_INVALID_ARG
;
209 GonkCameraParameters::MapIsoFromGonk(const char* aIso
, nsAString
& aIsoOut
)
211 if (strcmp(aIso
, "ISO_HJR") == 0) {
212 aIsoOut
.AssignASCII("hjr");
213 } else if (strcmp(aIso
, "auto") == 0) {
214 aIsoOut
.AssignASCII("auto");
218 // Some camera libraries return ISO modes as "ISO100", others as "100".
219 if (sscanf(aIso
, "ISO%u%c", &iso
, &ignored
) != 1 &&
220 sscanf(aIso
, "%u%c", &iso
, &ignored
) != 1) {
221 return NS_ERROR_INVALID_ARG
;
224 aIsoOut
.AppendInt(iso
);
230 // Any members that need to be initialized on the first parameter pull
231 // need to get handled in here.
233 GonkCameraParameters::Initialize()
237 rv
= GetImpl(Parameters::KEY_EXPOSURE_COMPENSATION_STEP
, mExposureCompensationStep
);
239 NS_WARNING("Failed to initialize exposure compensation step size");
240 mExposureCompensationStep
= 0.0;
242 rv
= GetImpl(Parameters::KEY_MIN_EXPOSURE_COMPENSATION
, mExposureCompensationMinIndex
);
244 NS_WARNING("Failed to initialize minimum exposure compensation index");
245 mExposureCompensationMinIndex
= 0;
247 rv
= GetImpl(Parameters::KEY_MAX_EXPOSURE_COMPENSATION
, mExposureCompensationMaxIndex
);
249 NS_WARNING("Failed to initialize maximum exposure compensation index");
250 mExposureCompensationMaxIndex
= 0;
253 rv
= GetListAsArray(CAMERA_PARAM_SUPPORTED_ZOOMRATIOS
, mZoomRatios
);
255 // zoom is not supported
258 for (uint32_t i
= 1; i
< mZoomRatios
.Length(); ++i
) {
259 // Make sure the camera gave us a properly sorted zoom ratio list!
260 if (mZoomRatios
[i
] < mZoomRatios
[i
- 1]) {
261 NS_WARNING("Zoom ratios list is out of order, discarding");
262 DOM_CAMERA_LOGE("zoom[%d]=%fx < zoom[%d]=%fx is out of order\n",
263 i
, mZoomRatios
[i
] / 100.0, i
- 1, mZoomRatios
[i
- 1] / 100.0);
268 if (mZoomRatios
.Length() == 0) {
269 // Always report that we support at least 1.0x zoom.
270 *mZoomRatios
.AppendElement() = 100;
273 // The return code from GetListAsArray() doesn't matter. If it fails,
274 // the isoModes array will be empty, and the subsequent loop won't
277 nsTArray
<nsCString
> isoModes
;
278 GetListAsArray(CAMERA_PARAM_SUPPORTED_ISOMODES
, isoModes
);
279 for (nsTArray
<nsCString
>::size_type i
= 0; i
< isoModes
.Length(); ++i
) {
280 rv
= MapIsoFromGonk(isoModes
[i
].get(), s
);
282 DOM_CAMERA_LOGW("Unrecognized ISO mode value '%s'\n", isoModes
[i
].get());
285 *mIsoModes
.AppendElement() = s
;
286 mIsoModeMap
.Put(s
, new nsCString(isoModes
[i
]));
289 GetListAsArray(CAMERA_PARAM_SUPPORTED_SCENEMODES
, mSceneModes
);
290 if (IsLowMemoryPlatform()) {
291 bool hdrRemoved
= false;
292 while (mSceneModes
.RemoveElement(NS_LITERAL_STRING("hdr"))) {
296 DOM_CAMERA_LOGI("Disabling HDR support due to low memory\n");
306 GonkCameraParameters::SetTranslated(uint32_t aKey
, const nsAString
& aValue
)
309 case CAMERA_PARAM_ISOMODE
:
312 nsresult rv
= MapIsoToGonk(aValue
, v
);
316 return SetImpl(aKey
, v
.get());
319 case CAMERA_PARAM_SCENEMODE
:
320 if (mSceneModes
.IndexOf(aValue
) == nsTArray
<nsString
>::NoIndex
) {
321 return NS_ERROR_INVALID_ARG
;
326 return SetImpl(aKey
, NS_ConvertUTF16toUTF8(aValue
).get());
331 GonkCameraParameters::GetTranslated(uint32_t aKey
, nsAString
& aValue
)
334 nsresult rv
= GetImpl(aKey
, val
);
338 if (aKey
== CAMERA_PARAM_ISOMODE
) {
339 rv
= MapIsoFromGonk(val
, aValue
);
341 aValue
.AssignASCII(val
);
348 // Handle ICameraControl::Sizes
350 GonkCameraParameters::SetTranslated(uint32_t aKey
, const ICameraControl::Size
& aSize
)
352 if (aSize
.width
> INT_MAX
|| aSize
.height
> INT_MAX
) {
353 // AOSP can only handle signed ints.
354 DOM_CAMERA_LOGE("Camera parameter aKey=%d out of bounds (width=%u, height=%u)\n",
355 aSize
.width
, aSize
.height
);
356 return NS_ERROR_INVALID_ARG
;
362 case CAMERA_PARAM_THUMBNAILSIZE
:
363 // This is a special case--for some reason the thumbnail size
364 // is accessed as two separate values instead of a tuple.
365 // XXXmikeh - make this restore the original values on error
366 rv
= SetImpl(Parameters::KEY_JPEG_THUMBNAIL_WIDTH
, static_cast<int>(aSize
.width
));
367 if (NS_SUCCEEDED(rv
)) {
368 rv
= SetImpl(Parameters::KEY_JPEG_THUMBNAIL_HEIGHT
, static_cast<int>(aSize
.height
));
372 case CAMERA_PARAM_VIDEOSIZE
:
373 // "record-size" is probably deprecated in later ICS;
374 // might need to set "video-size" instead of "record-size";
375 // for the time being, set both. See bug 795332.
376 rv
= SetImpl("record-size", nsPrintfCString("%ux%u", aSize
.width
, aSize
.height
).get());
380 // intentional fallthrough
383 rv
= SetImpl(aKey
, nsPrintfCString("%ux%u", aSize
.width
, aSize
.height
).get());
388 DOM_CAMERA_LOGE("Camera parameter aKey=%d failed to set (0x%x)\n", aKey
, rv
);
394 GonkCameraParameters::GetTranslated(uint32_t aKey
, ICameraControl::Size
& aSize
)
398 if (aKey
== CAMERA_PARAM_THUMBNAILSIZE
) {
402 rv
= GetImpl(Parameters::KEY_JPEG_THUMBNAIL_WIDTH
, width
);
407 return NS_ERROR_NOT_AVAILABLE
;
409 rv
= GetImpl(Parameters::KEY_JPEG_THUMBNAIL_HEIGHT
, height
);
414 return NS_ERROR_NOT_AVAILABLE
;
417 aSize
.width
= static_cast<uint32_t>(width
);
418 aSize
.height
= static_cast<uint32_t>(height
);
423 rv
= GetImpl(aKey
, value
);
427 if (!value
|| *value
== '\0') {
428 DOM_CAMERA_LOGW("Camera parameter aKey=%d not available\n", aKey
);
429 return NS_ERROR_NOT_AVAILABLE
;
431 if (sscanf(value
, "%ux%u", &aSize
.width
, &aSize
.height
) != 2) {
432 DOM_CAMERA_LOGE("Camera parameter aKey=%d size tuple '%s' is invalid\n", aKey
, value
);
433 return NS_ERROR_NOT_AVAILABLE
;
439 // Handle arrays of ICameraControl::Regions
441 GonkCameraParameters::SetTranslated(uint32_t aKey
, const nsTArray
<ICameraControl::Region
>& aRegions
)
443 uint32_t length
= aRegions
.Length();
446 // This tells the camera driver to revert to automatic regioning.
447 return SetImpl(aKey
, "(0,0,0,0,0)");
452 for (uint32_t i
= 0; i
< length
; ++i
) {
453 const ICameraControl::Region
* r
= &aRegions
[i
];
454 s
.AppendPrintf("(%d,%d,%d,%d,%d),", r
->left
, r
->top
, r
->right
, r
->bottom
, r
->weight
);
457 // remove the trailing comma
458 s
.Trim(",", false, true, true);
460 return SetImpl(aKey
, s
.get());
464 GonkCameraParameters::GetTranslated(uint32_t aKey
, nsTArray
<ICameraControl::Region
>& aRegions
)
469 nsresult rv
= GetImpl(aKey
, value
);
473 if (!value
|| *value
== '\0') {
474 DOM_CAMERA_LOGW("Camera parameter aKey=%d not available\n", aKey
);
475 return NS_ERROR_NOT_AVAILABLE
;
478 const char* p
= value
;
481 // count the number of regions in the string
482 while ((p
= strstr(p
, "),("))) {
487 aRegions
.SetCapacity(count
);
488 ICameraControl::Region
* r
;
490 // parse all of the region sets
492 for (i
= 0, p
= value
; p
&& i
< count
; ++i
, p
= strchr(p
+ 1, '(')) {
493 r
= aRegions
.AppendElement();
494 if (sscanf(p
, "(%d,%d,%d,%d,%u)", &r
->left
, &r
->top
, &r
->right
, &r
->bottom
, &r
->weight
) != 5) {
495 DOM_CAMERA_LOGE("Camera parameter aKey=%d region tuple has bad format: '%s'\n", aKey
, p
);
497 return NS_ERROR_NOT_AVAILABLE
;
504 // Handle ICameraControl::Positions
506 GonkCameraParameters::SetTranslated(uint32_t aKey
, const ICameraControl::Position
& aPosition
)
508 MOZ_ASSERT(aKey
== CAMERA_PARAM_PICTURE_LOCATION
);
510 // Add any specified location information -- we don't care if these fail.
511 if (!isnan(aPosition
.latitude
)) {
512 DOM_CAMERA_LOGI("setting picture latitude to %lf\n", aPosition
.latitude
);
513 SetImpl(Parameters::KEY_GPS_LATITUDE
, nsPrintfCString("%lf", aPosition
.latitude
).get());
515 if (!isnan(aPosition
.longitude
)) {
516 DOM_CAMERA_LOGI("setting picture longitude to %lf\n", aPosition
.longitude
);
517 SetImpl(Parameters::KEY_GPS_LONGITUDE
, nsPrintfCString("%lf", aPosition
.longitude
).get());
519 if (!isnan(aPosition
.altitude
)) {
520 DOM_CAMERA_LOGI("setting picture altitude to %lf\n", aPosition
.altitude
);
521 SetImpl(Parameters::KEY_GPS_ALTITUDE
, nsPrintfCString("%lf", aPosition
.altitude
).get());
523 if (!isnan(aPosition
.timestamp
)) {
524 DOM_CAMERA_LOGI("setting picture timestamp to %lf\n", aPosition
.timestamp
);
525 SetImpl(Parameters::KEY_GPS_TIMESTAMP
, nsPrintfCString("%lf", aPosition
.timestamp
).get());
533 GonkCameraParameters::SetTranslated(uint32_t aKey
, const int64_t& aValue
)
536 case CAMERA_PARAM_PICTURE_DATETIME
:
538 // Add the non-GPS timestamp. The EXIF date/time field is formatted as
539 // "YYYY:MM:DD HH:MM:SS", without room for a time-zone; as such, the time
540 // is meant to be stored as a local time. Since we are given seconds from
541 // Epoch GMT, we use localtime_r() to handle the conversion.
542 time_t time
= aValue
;
543 if (time
!= aValue
) {
544 DOM_CAMERA_LOGE("picture date/time '%llu' is too far in the future\n", aValue
);
545 return NS_ERROR_INVALID_ARG
;
549 if (!localtime_r(&time
, &t
)) {
550 DOM_CAMERA_LOGE("picture date/time couldn't be converted to local time: (%d) %s\n", errno
, strerror(errno
));
551 return NS_ERROR_FAILURE
;
555 if (!strftime(dateTime
, sizeof(dateTime
), "%Y:%m:%d %T", &t
)) {
556 DOM_CAMERA_LOGE("picture date/time couldn't be converted to string\n");
557 return NS_ERROR_FAILURE
;
560 DOM_CAMERA_LOGI("setting picture date/time to %s\n", dateTime
);
562 return SetImpl(CAMERA_PARAM_PICTURE_DATETIME
, dateTime
);
565 case CAMERA_PARAM_ISOMODE
:
567 if (aValue
> INT32_MAX
) {
568 DOM_CAMERA_LOGW("Can't set ISO mode = %lld, too big\n", aValue
);
569 return NS_ERROR_INVALID_ARG
;
574 return SetTranslated(CAMERA_PARAM_ISOMODE
, s
);
578 // You can't actually pass 64-bit parameters to Gonk. :(
579 int32_t v
= static_cast<int32_t>(aValue
);
580 if (static_cast<int64_t>(v
) != aValue
) {
581 return NS_ERROR_INVALID_ARG
;;
583 return SetImpl(aKey
, v
);
587 GonkCameraParameters::GetTranslated(uint32_t aKey
, int64_t& aValue
)
590 nsresult rv
= GetImpl(aKey
, val
);
600 GonkCameraParameters::SetTranslated(uint32_t aKey
, const double& aValue
)
606 case CAMERA_PARAM_EXPOSURECOMPENSATION
:
607 if (mExposureCompensationStep
== 0.0) {
608 DOM_CAMERA_LOGE("Exposure compensation not supported, can't set EV=%f\n", aValue
);
609 return NS_ERROR_NOT_AVAILABLE
;
613 * Convert from real value to a Gonk index, round
614 * to the nearest step; index is 1-based.
617 double i
= round(aValue
/ mExposureCompensationStep
);
618 if (i
< mExposureCompensationMinIndex
) {
619 index
= mExposureCompensationMinIndex
;
620 } else if (i
> mExposureCompensationMaxIndex
) {
621 index
= mExposureCompensationMaxIndex
;
626 DOM_CAMERA_LOGI("Exposure compensation = %f --> index = %d\n", aValue
, index
);
627 return SetImpl(CAMERA_PARAM_EXPOSURECOMPENSATION
, index
);
629 case CAMERA_PARAM_ZOOM
:
632 * Convert from a real zoom multipler (e.g. 2.5x) to
633 * the index of the nearest supported value.
635 value
= aValue
* 100.0;
637 if (value
<= mZoomRatios
[0]) {
639 } else if (value
>= mZoomRatios
.LastElement()) {
640 index
= mZoomRatios
.Length() - 1;
642 // mZoomRatios is sorted, so we can binary search it
644 int top
= mZoomRatios
.Length() - 1;
646 while (top
>= bottom
) {
647 index
= (top
+ bottom
) / 2;
648 if (value
== mZoomRatios
[index
]) {
652 if (value
> mZoomRatios
[index
] && value
< mZoomRatios
[index
+ 1]) {
653 // the specified zoom value lies in this interval
656 if (value
> mZoomRatios
[index
]) {
663 DOM_CAMERA_LOGI("Zoom = %fx --> index = %d\n", aValue
, index
);
665 return SetImpl(CAMERA_PARAM_ZOOM
, index
);
667 case CAMERA_PARAM_PICTURE_QUALITY
:
669 // Convert aValue [0.0..1.0] to nearest index in the range [1..100].
670 index
= (aValue
+ 0.005) * 99.0 + 1.0;
673 } else if (aValue
> 1.0) {
676 DOM_CAMERA_LOGI("Picture quality = %f --> index = %d\n", aValue
, index
);
678 return SetImpl(CAMERA_PARAM_PICTURE_QUALITY
, index
);
681 return SetImpl(aKey
, aValue
);
685 GonkCameraParameters::GetTranslated(uint32_t aKey
, double& aValue
)
687 double val
= 0.0; // initialize to keep the compiler happy [-Wmaybe-uninitialized]
689 double focusDistance
[3];
694 case CAMERA_PARAM_ZOOM
:
695 rv
= GetImpl(aKey
, index
);
696 if (NS_SUCCEEDED(rv
) && index
>= 0) {
697 val
= mZoomRatios
[index
] / 100.0;
699 // return 1x when zooming is not supported
706 * The gonk camera parameters API only exposes one focus distance property
707 * that contains "Near,Optimum,Far" distances, in metres, where 'Far' may
710 case CAMERA_PARAM_FOCUSDISTANCEFAR
:
712 // intentional fallthrough
714 case CAMERA_PARAM_FOCUSDISTANCEOPTIMUM
:
716 // intentional fallthrough
718 case CAMERA_PARAM_FOCUSDISTANCENEAR
:
719 rv
= GetImpl(aKey
, s
);
720 if (NS_SUCCEEDED(rv
)) {
721 if (sscanf(s
, "%lf,%lf,%lf", &focusDistance
[0], &focusDistance
[1], &focusDistance
[2]) == 3) {
722 val
= focusDistance
[index
];
729 case CAMERA_PARAM_EXPOSURECOMPENSATION
:
730 case CAMERA_PARAM_SUPPORTED_MINEXPOSURECOMPENSATION
:
731 case CAMERA_PARAM_SUPPORTED_MAXEXPOSURECOMPENSATION
:
732 if (mExposureCompensationStep
== 0.0) {
733 DOM_CAMERA_LOGE("Exposure compensation not supported, can't get EV\n");
734 return NS_ERROR_NOT_AVAILABLE
;
736 rv
= GetImpl(aKey
, index
);
737 if (NS_SUCCEEDED(rv
)) {
738 val
= index
* mExposureCompensationStep
;
739 DOM_CAMERA_LOGI("exposure compensation (aKey=%d): index=%d --> EV=%f\n", aKey
, index
, val
);
743 case CAMERA_PARAM_PICTURE_QUALITY
:
744 // Convert index [1..100] to a quality value [0.0..1.0].
745 rv
= GetImpl(aKey
, index
);
748 } else if (index
> 99) {
751 val
= static_cast<double>(index
- 1) / 99.0;
753 DOM_CAMERA_LOGI("index = %d --> picture quality = %f\n", index
, val
);
757 rv
= GetImpl(aKey
, val
);
761 if (NS_SUCCEEDED(rv
)) {
769 GonkCameraParameters::SetTranslated(uint32_t aKey
, const int& aValue
)
771 return SetImpl(aKey
, aValue
);
775 GonkCameraParameters::GetTranslated(uint32_t aKey
, int& aValue
)
777 return GetImpl(aKey
, aValue
);
780 // Handle uint32_ts -- Gonk only speaks int
782 GonkCameraParameters::SetTranslated(uint32_t aKey
, const uint32_t& aValue
)
784 if (aValue
> INT_MAX
) {
785 return NS_ERROR_INVALID_ARG
;
788 int val
= static_cast<int>(aValue
);
789 return SetImpl(aKey
, val
);
793 GonkCameraParameters::GetTranslated(uint32_t aKey
, uint32_t& aValue
)
796 nsresult rv
= GetImpl(aKey
, val
);
801 return NS_ERROR_NOT_AVAILABLE
;
810 GonkCameraParameters::SetTranslated(uint32_t aKey
, const bool& aValue
)
812 return SetImpl(aKey
, aValue
);
816 GonkCameraParameters::GetTranslated(uint32_t aKey
, bool& aValue
)
818 return GetImpl(aKey
, aValue
);
822 ParseItem(const char* aStart
, const char* aEnd
, ICameraControl::Size
* aItem
)
824 if (sscanf(aStart
, "%ux%u", &aItem
->width
, &aItem
->height
) == 2) {
828 DOM_CAMERA_LOGE("Size tuple has bad format: '%s'\n", aStart
);
829 return NS_ERROR_NOT_AVAILABLE
;
833 ParseItem(const char* aStart
, const char* aEnd
, nsAString
* aItem
)
836 aItem
->AssignASCII(aStart
, aEnd
- aStart
);
838 aItem
->AssignASCII(aStart
);
844 ParseItem(const char* aStart
, const char* aEnd
, nsACString
* aItem
)
847 aItem
->AssignASCII(aStart
, aEnd
- aStart
);
849 aItem
->AssignASCII(aStart
);
855 ParseItem(const char* aStart
, const char* aEnd
, double* aItem
)
857 if (sscanf(aStart
, "%lf", aItem
) == 1) {
861 return NS_ERROR_NOT_AVAILABLE
;
865 ParseItem(const char* aStart
, const char* aEnd
, int* aItem
)
867 if (sscanf(aStart
, "%d", aItem
) == 1) {
871 return NS_ERROR_NOT_AVAILABLE
;
874 template<class T
> nsresult
875 GonkCameraParameters::GetListAsArray(uint32_t aKey
, nsTArray
<T
>& aArray
)
878 nsresult rv
= GetImpl(aKey
, p
);
885 // If there is no value available, just return the empty array.
887 DOM_CAMERA_LOGI("Camera parameter %d not available (value is null)\n", aKey
);
891 DOM_CAMERA_LOGI("Camera parameter %d not available (value is empty string)\n", aKey
);
898 // nsTArray::AppendElement() is infallible
899 T
* v
= aArray
.AppendElement();
900 comma
= strchr(p
, ',');
902 rv
= ParseItem(p
, comma
, v
);
918 GonkCameraParameters::GetTranslated(uint32_t aKey
, nsTArray
<nsString
>& aValues
)
921 case CAMERA_PARAM_SUPPORTED_ISOMODES
:
925 case CAMERA_PARAM_SUPPORTED_SCENEMODES
:
926 aValues
= mSceneModes
;
930 return GetListAsArray(aKey
, aValues
);
935 GonkCameraParameters::GetTranslated(uint32_t aKey
, nsTArray
<double>& aValues
)
937 if (aKey
== CAMERA_PARAM_SUPPORTED_ZOOMRATIOS
) {
939 for (uint32_t i
= 0; i
< mZoomRatios
.Length(); ++i
) {
940 *aValues
.AppendElement() = mZoomRatios
[i
] / 100.0;
945 return GetListAsArray(aKey
, aValues
);
949 GonkCameraParameters::GetTranslated(uint32_t aKey
, nsTArray
<ICameraControl::Size
>& aSizes
)
951 return GetListAsArray(aKey
, aSizes
);