1 /* |
|
2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QMetaType> |
|
19 #include <QImage> |
|
20 #include <fbs.h> |
|
21 #include <ecam.h> // CCamera |
|
22 #include <ecam/ecamadvsettingsintf.h> // CCamera |
|
23 #include <ecamadvsettings.h> |
|
24 |
|
25 #include "cxesettings.h" |
|
26 #include "cxeautofocuscontrolsymbian.h" |
|
27 #include "cxutils.h" |
|
28 #include "cxecameradevice.h" // CxeCameraDevice |
|
29 #include "cxesettingsmappersymbian.h" |
|
30 #include "cxeerrormappingsymbian.h" |
|
31 #include "cxestate.h" |
|
32 |
|
33 #include "OstTraceDefinitions.h" |
|
34 #ifdef OST_TRACE_COMPILER_IN_USE |
|
35 #include "cxeautofocuscontrolsymbianTraces.h" |
|
36 #endif |
|
37 |
|
38 |
|
39 |
|
40 /* |
|
41 * CxeAutoFocusControlSymbian::CxeAutoFocusControlSymbian |
|
42 */ |
|
43 CxeAutoFocusControlSymbian::CxeAutoFocusControlSymbian(CxeCameraDevice &cameraDevice, |
|
44 CxeSettings &settings) |
|
45 : CxeStateMachine("CxeAutoFocusControlSymbian"), |
|
46 mCameraDevice(cameraDevice), |
|
47 mAdvancedSettings(NULL), |
|
48 mSettings(settings), |
|
49 mCancelled(false), |
|
50 mFaceTrackingOverride(false) |
|
51 { |
|
52 CX_DEBUG_ENTER_FUNCTION(); |
|
53 |
|
54 qRegisterMetaType<CxeAutoFocusControl::State>(); |
|
55 |
|
56 initializeStates(); |
|
57 |
|
58 OstTrace0(camerax_performance, CXEAUTOFOCUSCONTROLSYMBIAN_CREATE_MID1, "msg: e_CX_ENGINE_CONNECT_SIGNALS 1"); |
|
59 // connect signals from cameraDevice, so we recieve events when camera reference changes |
|
60 QObject::connect( &cameraDevice, |
|
61 SIGNAL(prepareForCameraDelete()), |
|
62 this,SLOT(prepareForCameraDelete()) ); |
|
63 |
|
64 QObject::connect( &cameraDevice, |
|
65 SIGNAL(cameraAllocated(CxeError::Id)), |
|
66 this,SLOT(handleCameraAllocated(CxeError::Id)) ); |
|
67 |
|
68 QObject::connect( &cameraDevice, |
|
69 SIGNAL(prepareForRelease()), |
|
70 this,SLOT(prepareForRelease()) ); |
|
71 |
|
72 // connect scene / setting change callbacks to settings control |
|
73 QObject::connect(&mSettings, |
|
74 SIGNAL(settingValueChanged(const QString&,QVariant)), |
|
75 this, |
|
76 SLOT(handleSettingValueChanged(const QString&,QVariant))); |
|
77 |
|
78 OstTrace0(camerax_performance, CXEAUTOFOCUSCONTROLSYMBIAN_CREATE_MID2, "msg: e_CX_ENGINE_CONNECT_SIGNALS 0"); |
|
79 |
|
80 initializeResources(); |
|
81 |
|
82 setMode(CxeAutoFocusControl::Hyperfocal); |
|
83 // autofocus sounds should be disabled by default |
|
84 mSoundEnabled = false; |
|
85 |
|
86 CX_DEBUG_EXIT_FUNCTION(); |
|
87 } |
|
88 |
|
89 |
|
90 |
|
91 /* |
|
92 * CxeAutoFocusControlSymbian::~CxeAutoFocusControlSymbian |
|
93 */ |
|
94 CxeAutoFocusControlSymbian::~CxeAutoFocusControlSymbian() |
|
95 { |
|
96 CX_DEBUG_ENTER_FUNCTION(); |
|
97 CX_DEBUG_EXIT_FUNCTION(); |
|
98 } |
|
99 |
|
100 |
|
101 /* |
|
102 * Start Autofocus |
|
103 * \param soundEnabled False if the auto focus sound don't need to be played |
|
104 * Default value for soundEnabled is true |
|
105 */ |
|
106 CxeError::Id CxeAutoFocusControlSymbian::start(bool soundEnabled) |
|
107 { |
|
108 CX_ASSERT_ALWAYS(mAdvancedSettings); |
|
109 |
|
110 CX_DEBUG( ("CxeAutoFocusControlSymbian::start() <> state: %d, sound enabled: %d", |
|
111 state(), soundEnabled ) ); |
|
112 |
|
113 mSoundEnabled = soundEnabled; |
|
114 CxeError::Id error = CxeError::None; |
|
115 |
|
116 if (!isFixedFocusMode(mode())) { |
|
117 if ( state() != CxeAutoFocusControl::InProgress && state() != CxeAutoFocusControl::Canceling ) { |
|
118 CX_DEBUG(("CxeAutoFocusControlSymbian::start() calling SetAutoFocusType")); |
|
119 mCancelled = false; |
|
120 setState(InProgress); |
|
121 setFocusRange(mAFRange); |
|
122 setFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle); |
|
123 } else { // AF was started earlier, can't start until it completes |
|
124 error = CxeError::InUse; |
|
125 } |
|
126 } |
|
127 |
|
128 CX_DEBUG( ("CxeAutoFocusControlSymbian::start() <= error: %d", error ) ); |
|
129 return error; |
|
130 } |
|
131 |
|
132 |
|
133 |
|
134 /* |
|
135 * Cancel Autofocus |
|
136 */ |
|
137 void CxeAutoFocusControlSymbian::cancel() |
|
138 { |
|
139 CX_DEBUG( ("CxeAutoFocusControlSymbian::cancel <> state: %d", state() ) ); |
|
140 |
|
141 CX_DEBUG_ASSERT(mAdvancedSettings); |
|
142 |
|
143 if (!mCancelled && !isFixedFocusMode(mode())) { |
|
144 if (state() == CxeAutoFocusControl::InProgress) { |
|
145 // Need to stop current AF first. Wait for AF event to proceed. |
|
146 setState(CxeAutoFocusControl::Canceling); |
|
147 setFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff); |
|
148 |
|
149 } else if (state() != CxeAutoFocusControl::Canceling) { |
|
150 // Cancel means move to hyperfocal. |
|
151 setState(CxeAutoFocusControl::Canceling); |
|
152 CX_DEBUG(("CxeAutoFocusControlSymbian::cancel() moving to hyperfocal")); |
|
153 setFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeHyperfocal); |
|
154 setFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle); |
|
155 } |
|
156 } |
|
157 CX_DEBUG_EXIT_FUNCTION(); |
|
158 } |
|
159 |
|
160 |
|
161 |
|
162 /* |
|
163 * Set Autofocus mode |
|
164 */ |
|
165 void CxeAutoFocusControlSymbian::setMode(CxeAutoFocusControl::Mode newMode) |
|
166 { |
|
167 CX_DEBUG_ENTER_FUNCTION(); |
|
168 |
|
169 CX_DEBUG_ASSERT(mAdvancedSettings); |
|
170 |
|
171 mAfMode = newMode; |
|
172 mAFRange = CxeSettingsMapperSymbian::Map2CameraAutofocus(mAfMode); |
|
173 |
|
174 CX_DEBUG(("CxeAutoFocusControlSymbian::setMode() mAFRange: %d", mAFRange)); |
|
175 |
|
176 mCancelled = false; |
|
177 setFocusRange(mAFRange); |
|
178 |
|
179 CX_DEBUG_EXIT_FUNCTION(); |
|
180 } |
|
181 |
|
182 |
|
183 /* |
|
184 * returns Autofocus mode |
|
185 */ |
|
186 CxeAutoFocusControl::Mode CxeAutoFocusControlSymbian::mode() const |
|
187 { |
|
188 return mAfMode; |
|
189 } |
|
190 |
|
191 /** |
|
192 * Is the given mode a fixed focus mode? |
|
193 */ |
|
194 bool CxeAutoFocusControlSymbian::isFixedFocusMode(CxeAutoFocusControl::Mode mode) const |
|
195 { |
|
196 return (mode == CxeAutoFocusControl::Hyperfocal |
|
197 || mode == CxeAutoFocusControl::Infinity); |
|
198 } |
|
199 |
|
200 /* |
|
201 * To check if Autofocus is supported |
|
202 */ |
|
203 bool CxeAutoFocusControlSymbian::supported() const |
|
204 { |
|
205 CX_DEBUG_ENTER_FUNCTION(); |
|
206 |
|
207 bool supported = |
|
208 (supportedFocusTypes() != CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff); |
|
209 |
|
210 CX_DEBUG_EXIT_FUNCTION(); |
|
211 return supported; |
|
212 } |
|
213 |
|
214 |
|
215 |
|
216 /* |
|
217 * Slot for handling ECam events |
|
218 */ |
|
219 void CxeAutoFocusControlSymbian::handleCameraEvent(int eventUid, int error) |
|
220 { |
|
221 CX_DEBUG_ENTER_FUNCTION(); |
|
222 |
|
223 CX_DEBUG( ("CxeAutoFocusControlSymbian::handleCameraEvent <> state: %d error %d", state(), error ) ); |
|
224 CX_DEBUG( ("CxeAutoFocusControlSymbian::handleCameraEvent <> uid: %x optimalfocusuid: %x focustype2uid %x", |
|
225 eventUid, |
|
226 KUidECamEventCameraSettingsOptimalFocusUidValue, |
|
227 KUidECamEventCameraSettingAutoFocusType2UidValue )); |
|
228 |
|
229 // We're only interested in autofocus events |
|
230 if ( eventUid == KUidECamEventCameraSettingsOptimalFocusUidValue || |
|
231 eventUid == KUidECamEventCameraSettingAutoFocusType2UidValue || |
|
232 eventUid == KUidECamEventCameraSettingFocusRangeUidValue) { |
|
233 // Autofocus Event handle it. |
|
234 handleAfEvent(eventUid, error); |
|
235 } |
|
236 |
|
237 CX_DEBUG_EXIT_FUNCTION(); |
|
238 } |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 void CxeAutoFocusControlSymbian::prepareForRelease() |
|
244 { |
|
245 |
|
246 CX_DEBUG_ENTER_FUNCTION(); |
|
247 |
|
248 // camera is anyway released, so no need to cancel the AF anyway |
|
249 setState(CxeAutoFocusControl::Unknown); |
|
250 mCancelled = false; |
|
251 |
|
252 CX_DEBUG_EXIT_FUNCTION(); |
|
253 |
|
254 } |
|
255 |
|
256 |
|
257 |
|
258 /* |
|
259 * camera reference changing, release resources |
|
260 */ |
|
261 void CxeAutoFocusControlSymbian::prepareForCameraDelete() |
|
262 { |
|
263 CX_DEBUG_ENTER_FUNCTION(); |
|
264 |
|
265 prepareForRelease(); |
|
266 mAdvancedSettings = NULL; |
|
267 |
|
268 CX_DEBUG_EXIT_FUNCTION(); |
|
269 } |
|
270 |
|
271 |
|
272 |
|
273 /* |
|
274 * new camera available, |
|
275 */ |
|
276 void CxeAutoFocusControlSymbian::handleCameraAllocated(CxeError::Id error) |
|
277 { |
|
278 CX_DEBUG_ENTER_FUNCTION(); |
|
279 if (!error) { |
|
280 setState(CxeAutoFocusControl::Unknown); |
|
281 mCancelled = false; |
|
282 initializeResources(); |
|
283 } |
|
284 CX_DEBUG_EXIT_FUNCTION(); |
|
285 } |
|
286 |
|
287 /* |
|
288 * CxeAutoFocusControlSymbian::state |
|
289 */ |
|
290 CxeAutoFocusControl::State CxeAutoFocusControlSymbian::state() const |
|
291 { |
|
292 return static_cast<State>( stateId() ); |
|
293 } |
|
294 |
|
295 /* |
|
296 * CxeAutoFocusControlSymbian::handleStateChanged |
|
297 */ |
|
298 void CxeAutoFocusControlSymbian::handleStateChanged( int newStateId, CxeError::Id error ) |
|
299 { |
|
300 emit stateChanged(static_cast<State>(newStateId), error); |
|
301 } |
|
302 |
|
303 /* |
|
304 * CxeAutoFocusControlSymbian::initializeStates |
|
305 */ |
|
306 void CxeAutoFocusControlSymbian::initializeStates() |
|
307 { |
|
308 // addState( id, name, allowed next states ) |
|
309 addState( new CxeState( Unknown , "Unknown", InProgress | Canceling ) ); |
|
310 addState( new CxeState( InProgress , "InProgress", Unknown | Failed | Ready | Canceling ) ); |
|
311 addState( new CxeState( Failed , "Failed", InProgress | Unknown | Canceling ) ); |
|
312 addState( new CxeState( Ready , "Ready", Unknown | InProgress | Canceling ) ); |
|
313 addState( new CxeState( Canceling , "Canceling", Unknown ) ); |
|
314 |
|
315 setInitialState( Unknown ); |
|
316 } |
|
317 |
|
318 /* |
|
319 * CxeAutoFocusControlSymbian::initializeResources |
|
320 */ |
|
321 void CxeAutoFocusControlSymbian::initializeResources() |
|
322 { |
|
323 CX_DEBUG_ENTER_FUNCTION(); |
|
324 |
|
325 // No check if non-null. Not supported if zero pointer (see supported() ). |
|
326 mAdvancedSettings = mCameraDevice.advancedSettings(); |
|
327 CX_ASSERT_ALWAYS(mAdvancedSettings); |
|
328 |
|
329 CX_DEBUG_EXIT_FUNCTION(); |
|
330 } |
|
331 |
|
332 |
|
333 /* |
|
334 * CxeAutoFocusControlSymbian::setFocusRange |
|
335 */ |
|
336 void CxeAutoFocusControlSymbian::setFocusRange(CCamera::CCameraAdvancedSettings::TFocusRange range) |
|
337 { |
|
338 CX_DEBUG_ENTER_FUNCTION(); |
|
339 CX_DEBUG_ASSERT(mAdvancedSettings); |
|
340 |
|
341 mAdvancedSettings->SetFocusRange(range); |
|
342 |
|
343 CX_DEBUG_EXIT_FUNCTION(); |
|
344 } |
|
345 |
|
346 /* |
|
347 * CxeAutoFocusControlSymbian::focusRange |
|
348 */ |
|
349 CCamera::CCameraAdvancedSettings::TFocusRange CxeAutoFocusControlSymbian::focusRange() const |
|
350 { |
|
351 CX_DEBUG_ENTER_FUNCTION(); |
|
352 const CCamera::CCameraAdvancedSettings::TFocusRange range( |
|
353 mAdvancedSettings |
|
354 ? mAdvancedSettings->FocusRange() |
|
355 : CCamera::CCameraAdvancedSettings::EFocusRangeAuto ); |
|
356 |
|
357 CX_DEBUG_EXIT_FUNCTION(); |
|
358 return range; |
|
359 } |
|
360 |
|
361 /* |
|
362 * CxeAutoFocusControlSymbian::setFocusType |
|
363 */ |
|
364 void CxeAutoFocusControlSymbian::setFocusType(CCamera::CCameraAdvancedSettings::TAutoFocusType type) |
|
365 { |
|
366 CX_DEBUG_ENTER_FUNCTION(); |
|
367 CX_DEBUG_ASSERT(mAdvancedSettings); |
|
368 |
|
369 mAdvancedSettings->SetAutoFocusType(type); |
|
370 |
|
371 CX_DEBUG_EXIT_FUNCTION(); |
|
372 } |
|
373 |
|
374 /* |
|
375 * CxeAutoFocusControlSymbian::supportedFocusTypes |
|
376 */ |
|
377 int CxeAutoFocusControlSymbian::supportedFocusTypes() const |
|
378 { |
|
379 CX_DEBUG_ENTER_FUNCTION(); |
|
380 |
|
381 const int support( mAdvancedSettings |
|
382 ? mAdvancedSettings->SupportedAutoFocusTypes() |
|
383 : CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff ); |
|
384 |
|
385 CX_DEBUG_EXIT_FUNCTION(); |
|
386 return support; |
|
387 } |
|
388 |
|
389 /* |
|
390 * CxeAutoFocusControlSymbian::focusType |
|
391 */ |
|
392 CCamera::CCameraAdvancedSettings::TAutoFocusType CxeAutoFocusControlSymbian::focusType() const |
|
393 { |
|
394 CX_DEBUG_ENTER_FUNCTION(); |
|
395 |
|
396 const CCamera::CCameraAdvancedSettings::TAutoFocusType type( |
|
397 mAdvancedSettings |
|
398 ? mAdvancedSettings->AutoFocusType() |
|
399 : CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff ); |
|
400 |
|
401 CX_DEBUG_EXIT_FUNCTION(); |
|
402 return type; |
|
403 } |
|
404 |
|
405 |
|
406 /* |
|
407 * Image Scene mode changed, get the new autofocus value |
|
408 */ |
|
409 void CxeAutoFocusControlSymbian::handleSceneChanged(const QVariant& sceneData) |
|
410 { |
|
411 CX_DEBUG_ENTER_FUNCTION(); |
|
412 |
|
413 CxeScene scene = sceneData.value<CxeScene>(); |
|
414 // whenever scene mode is changed we set the state to unknown |
|
415 setState(CxeAutoFocusControl::Unknown); |
|
416 |
|
417 // we are interested only in the AF range. |
|
418 if(scene.contains(CxeSettingIds::FOCAL_RANGE) && supported() ) { |
|
419 |
|
420 setMode(static_cast<CxeAutoFocusControl::Mode>(scene[CxeSettingIds::FOCAL_RANGE].toInt())); |
|
421 |
|
422 if (isFixedFocusMode(mode())) { |
|
423 // Focus now if a fixed focus mode is used. |
|
424 setFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle); |
|
425 // Set state to InProgress, so we know to set it ready in ECAM callback. |
|
426 setState(CxeAutoFocusControl::InProgress); |
|
427 } |
|
428 } |
|
429 |
|
430 CX_DEBUG_EXIT_FUNCTION(); |
|
431 } |
|
432 |
|
433 |
|
434 |
|
435 /* |
|
436 * CxeAutoFocusControlSymbian::handleAfEvent |
|
437 */ |
|
438 void CxeAutoFocusControlSymbian::handleAfEvent(int eventUid, int error) |
|
439 { |
|
440 CX_DEBUG_ENTER_FUNCTION(); |
|
441 |
|
442 switch ( state() ) { |
|
443 case CxeAutoFocusControl::InProgress: { |
|
444 if (eventUid == KUidECamEventCameraSettingsOptimalFocusUidValue ) { |
|
445 OstTrace0(camerax_performance, CXEAUTOFOCUSCONTROLSYMBIAN_AF_LOCK, "msg: e_CX_AUTOFOCUS_LOCK 0"); |
|
446 |
|
447 CX_DEBUG(("CxeAutoFocusControlSymbian::handleAfEvent <> KUidECamEventCameraSettingsOptimalFocus")); |
|
448 if (KErrNone == error) { |
|
449 setState(CxeAutoFocusControl::Ready); |
|
450 } else { |
|
451 setState(CxeAutoFocusControl::Failed, CxeErrorHandlingSymbian::map(error)); |
|
452 } |
|
453 } else if (eventUid == KUidECamEventCameraSettingFocusRangeUidValue) { |
|
454 // check for error, we don't need this event for anything else |
|
455 if (error != KErrNone) { |
|
456 CX_DEBUG(("CxeAutofocusControlSymbian::handleAfEvent <> " |
|
457 "KUidECamEventCameraSettingFocusRangeUidValue: autofocus failed %d", error)); |
|
458 setState(CxeAutoFocusControl::Failed, CxeErrorHandlingSymbian::map(error)); |
|
459 } |
|
460 } |
|
461 break; |
|
462 } |
|
463 case CxeAutoFocusControl::Canceling: { |
|
464 CX_DEBUG(("CxeAutoFocusControlSymbian::handleAfEvent <> Canceling")); |
|
465 // Cancelling started by setting AF off to stop ongoing focus operation. |
|
466 // Finalize cancelling by setting lens to hyperfocal position. |
|
467 if (eventUid == KUidECamEventCameraSettingAutoFocusType2UidValue) { |
|
468 if (focusType() == CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff) { |
|
469 setFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeHyperfocal); |
|
470 setFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle); |
|
471 } |
|
472 } else if (eventUid == KUidECamEventCameraSettingsOptimalFocusUidValue) { |
|
473 mCancelled = true; |
|
474 setState(CxeAutoFocusControl::Unknown); |
|
475 } |
|
476 |
|
477 break; |
|
478 } |
|
479 default: |
|
480 break; |
|
481 } // end switch |
|
482 |
|
483 CX_DEBUG_EXIT_FUNCTION(); |
|
484 } |
|
485 |
|
486 /*! |
|
487 * Public method for checking if auto focus sound is enabled |
|
488 * \return true if enabled |
|
489 */ |
|
490 bool CxeAutoFocusControlSymbian::isSoundEnabled() const |
|
491 { |
|
492 return mSoundEnabled; |
|
493 } |
|
494 |
|
495 /*! |
|
496 * Handle new setting value. |
|
497 * New value is set to camera. |
|
498 * \param settingId The id of the updated setting |
|
499 * \param newValue A new value for the updated setting |
|
500 */ |
|
501 void CxeAutoFocusControlSymbian::handleSettingValueChanged(const QString& settingId, QVariant newValue) |
|
502 { |
|
503 CX_DEBUG_ENTER_FUNCTION(); |
|
504 if (settingId == CxeSettingIds::FACE_TRACKING) { |
|
505 // Updating AF mode when face tracking is activated |
|
506 // in scene mode which doesn't support face tracking |
|
507 if (newValue.toInt()) { |
|
508 //Face tracking enabled |
|
509 if(mAfMode == CxeAutoFocusControl::Infinity || |
|
510 mAfMode == CxeAutoFocusControl::Hyperfocal) { |
|
511 mPreviousAFMode = mAfMode; |
|
512 setMode(CxeAutoFocusControl::Auto); |
|
513 mFaceTrackingOverride = true; |
|
514 } |
|
515 } else { |
|
516 //Face tracking disabled |
|
517 if (mFaceTrackingOverride) { |
|
518 mAfMode = mPreviousAFMode; |
|
519 setMode(mAfMode); |
|
520 mFaceTrackingOverride = false; |
|
521 } |
|
522 } |
|
523 |
|
524 } else { |
|
525 // do nothing |
|
526 } |
|
527 |
|
528 CX_DEBUG_EXIT_FUNCTION(); |
|
529 } |
|
530 |
|
531 // end of file |
|