2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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 * @author Grzegorz Krawczyk (g.krawczyk@samsung.com)
24 #include <dpl/assert.h>
25 #include <dpl/shared_ptr.h>
26 #include <dpl/noncopyable.h>
27 #include <Commons/Exception.h>
28 #include <Commons/TypeTraits.h>
31 namespace WrtDeviceApis {
34 template<typename EventPtr>
35 class CameraPrivateData
49 class OpaquePrivateData
52 EventTypeId eventTypeId;
53 void* cameraPrivateData;
59 EventTypeId getEventTypeId(const T& event){ Assert(0); }
62 EventTypeId getEventTypeId<Api::EventBeginRecordingSharedPtr>(
63 const Api::EventBeginRecordingSharedPtr& /*event*/)
65 return BeginRecordingType;
69 EventTypeId getEventTypeId<Api::EventTakePictureSharedPtr>(
70 const Api::EventTakePictureSharedPtr& /*event*/)
72 return TakePictureType;
76 EventTypeId getEventTypeId<Api::EventGetPreviewNodeSharedPtr>(
77 const Api::EventGetPreviewNodeSharedPtr& /*event*/)
79 return CreatePreviewType;
82 template<typename EventPtr>
83 OpaquePrivateData* createPrivateOpaqueData(Camera* camera,
84 const EventPtr& event)
86 //create private opaque data
87 OpaquePrivateData* opaqueData = new OpaquePrivateData;
89 CameraPrivateData<EventPtr>* privateData = new CameraPrivateData<EventPtr>;
90 privateData->camera = camera;
91 privateData->event = event;
93 opaqueData->eventTypeId = getEventTypeId(event);
94 opaqueData->cameraPrivateData = privateData;
99 template<typename EventPtr>
100 CameraPrivateData<EventPtr>* getPrivateData(void* data)
102 OpaquePrivateData* opaqueData = static_cast<OpaquePrivateData*> (data);
104 CameraPrivateData<EventPtr>* privateData =
105 static_cast<CameraPrivateData<EventPtr> *>
106 (opaqueData->cameraPrivateData);
111 template<typename EventPtr>
112 void deletePrivateData(void* data)
114 OpaquePrivateData* opaqueData = static_cast<OpaquePrivateData*> (data);
116 CameraPrivateData<EventPtr>* privateData =
117 static_cast<CameraPrivateData<EventPtr> *>
118 (opaqueData->cameraPrivateData);
125 template<typename EventType, typename EventArg>
126 EventType createEvent(const EventArg& arg1)
128 return EventType(arg1);
132 template<typename EventType>
133 class BaseCallbackHandler : private DPL::Noncopyable
136 explicit BaseCallbackHandler(void* data) :
140 CameraPrivateData<EventType>* privateData =
141 getPrivateData<EventType>(data);
142 m_camera = privateData->camera;
143 m_event = privateData->event;
145 deletePrivateData<EventType>(data);
148 virtual void handleErrorCallback(int error)
150 LogError("Error: " << error);
151 m_event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
155 virtual void handleSuccessCallback(void* data)
161 virtual void post() = 0;
163 virtual ~BaseCallbackHandler(){ }
166 virtual void setPrivate(void* /*data*/) {};
173 template<typename EventType>
174 class CallbackHandler : public BaseCallbackHandler<EventType>
176 static_assert(WrtDeviceApis::Commons::AlwaysFalse<EventType>::value,
177 "Error, no specialization found for given type");
180 explicit CallbackHandler(void* data) :
181 BaseCallbackHandler<EventType>(data)
185 //virtual void post(){ }
189 class CallbackHandler<Api::EventBeginRecordingSharedPtr>
190 : public BaseCallbackHandler<Api::EventBeginRecordingSharedPtr>
193 explicit CallbackHandler(void* data) :
194 BaseCallbackHandler(data)
198 this->m_camera->setRecordingState(Camera::COMPLETED);
200 DPL::Event::ControllerEventHandler<JobDoneVideoRecordingEvent>::PostEvent(
201 createEvent<JobDoneVideoRecordingEvent,
202 Api::EventBeginRecordingSharedPtr>(this->m_event));
205 virtual void handleSuccessCallback(void* data)
207 this->m_camera->setRecordingState(Camera::COMPLETED);
208 BaseCallbackHandler<Api::EventBeginRecordingSharedPtr>::
209 handleSuccessCallback(data);
214 class CallbackHandler<Api::EventTakePictureSharedPtr>
215 : public BaseCallbackHandler<Api::EventTakePictureSharedPtr>
218 explicit CallbackHandler(void* data) :
219 BaseCallbackHandler(data)
224 DPL::Event::ControllerEventHandler<JobDoneTakePictureEvent>::PostEvent(
225 createEvent<JobDoneTakePictureEvent,
226 Api::EventTakePictureSharedPtr>(this->m_event));
229 virtual void setPrivate(void* data)
231 m_event->getCaptureOptionsRef()->setFileName(static_cast<char*>(data));
236 class CallbackHandler<Api::EventGetPreviewNodeSharedPtr>
237 : public BaseCallbackHandler<Api::EventGetPreviewNodeSharedPtr>
240 explicit CallbackHandler(void* data) :
241 BaseCallbackHandler(data)
246 DPL::Event::ControllerEventHandler<JobDoneCreatePreviewEvent>::PostEvent(
247 createEvent<JobDoneCreatePreviewEvent,
248 Api::EventGetPreviewNodeSharedPtr>(this->m_event));
251 virtual void setPrivate(void* data)
254 m_event->setPreviewNode(data);
258 Camera::Camera(const Commons::IWrtCameraPtr& wrtCamera) :
259 m_wrtCamera(wrtCamera),
260 m_stateRecordingVideo (Camera::IDLE)
262 CameraJobDoneController::Touch();
269 CameraJobDoneController::SwitchToThread(NULL);
273 void Camera::OnRequestReceived(
274 const Api::EventTakePictureSharedPtr & event)
278 event->switchToManualAnswer();
280 m_wrtCamera->captureImage(event->getCaptureOptionsRef()->getFileName(),
281 checkHighResolutionRequired(event),
282 camCaptureImageSuccessCallback,
283 camCaptureImageErrorCallback,
285 createPrivateOpaqueData(this,event));
290 void Camera::OnRequestReceived(
291 const Api::EventBeginRecordingSharedPtr & event)
295 if (m_stateRecordingVideo != Camera::IDLE) {
296 event->setExceptionCode(Commons::ExceptionCodes::AlreadyInUseException);
299 m_stateRecordingVideo = Camera::PROCESSING;
301 //from now on we will have to call answer manually
302 event->switchToManualAnswer();
304 m_wrtCamera->startVideoCapture(event->getCaptureOptionsRef()->getFileName(),
305 checkHighResolutionRequired(event),
306 camCaptureVideoSuccessCallback,
307 camCaptureVideoErrorCallback,
309 createPrivateOpaqueData(this,event));
314 void Camera::OnRequestReceived(
315 const Api::EventEndRecordingSharedPtr & event)
317 LogDebug("end request");
318 if (m_stateRecordingVideo == Camera::PROCESSING) {
319 m_wrtCamera->stopVideoCapture();
321 LogDebug("stopVideo has been called but no recording is in progress");
322 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
326 void Camera::OnRequestReceived(
327 const Api::EventGetPreviewNodeSharedPtr & event)
331 event->switchToManualAnswer();
333 LogDebug("start createPreview");
335 m_wrtCamera->createPreviewNode(camPreviewSuccessCallback,
336 camPreviewErrorCallback,
338 createPrivateOpaqueData(this,event));
342 void Camera::camCaptureImageSuccessCallback(
343 const char* filename, void* data)
345 LogDebug("*Picture* Captured. !!!");
347 CallbackHandler<Api::EventTakePictureSharedPtr> handler(data);
348 handler.handleSuccessCallback(const_cast<char*>(filename));
351 void Camera::camCaptureVideoSuccessCallback(const char* filename, void* data)
353 LogDebug("*Video* Captured. !!!");
355 CallbackHandler<Api::EventBeginRecordingSharedPtr> handler(data);
356 handler.handleSuccessCallback(const_cast<char*>(filename));
359 void Camera::camPreviewSuccessCallback(
360 Commons::IWrtCamera::CameraPreviewNode node, void* data)
364 CallbackHandler<Api::EventGetPreviewNodeSharedPtr> handler(data);
365 handler.handleSuccessCallback(node);
368 void Camera::camPreviewErrorCallback(int errorCode, void* data)
372 CallbackHandler<Api::EventGetPreviewNodeSharedPtr> handler(data);
373 handler.handleErrorCallback(errorCode);
376 void Camera::camCaptureImageErrorCallback(int errorCode, void* data)
380 CallbackHandler<Api::EventTakePictureSharedPtr> handler(data);
381 handler.handleErrorCallback(errorCode);
384 void Camera::camCaptureVideoErrorCallback(int errorCode, void* data)
388 CallbackHandler<Api::EventBeginRecordingSharedPtr> handler(data);
389 handler.handleErrorCallback(errorCode);
392 void Camera::OnEventReceived(const JobDoneVideoRecordingEvent &event)
395 if (m_stateRecordingVideo == COMPLETED && event.GetArg0()) {
396 EventRequestReceiver<Api::EventBeginRecording>::
397 ManualAnswer(event.GetArg0());
400 m_stateRecordingVideo = Camera::IDLE;
403 void Camera::OnEventReceived(const JobDoneCreatePreviewEvent &event)
405 OnJobDoneReceived(event.GetArg0());
408 void Camera::OnEventReceived(const JobDoneTakePictureEvent &event)
410 OnJobDoneReceived(event.GetArg0());
413 void Camera::OnCancelEvent(
414 const Api::EventBeginRecordingSharedPtr& event)
416 LogDebug(__FUNCTION__);
418 if (Camera::PROCESSING == m_stateRecordingVideo) {
419 if (event->checkPendingOperation()) {
420 m_wrtCamera->cancelAsyncOperation(event->getPendingOperation());
422 setRecordingState(Camera::IDLE);
424 LogError("Cancel invoked, but the state is wrong");
428 void Camera::OnCancelEvent(const Api::EventTakePictureSharedPtr& event)
433 void Camera::OnCancelEvent(
434 const Api::EventGetPreviewNodeSharedPtr& event)
439 void Camera::setRecordingState(CameraState state)
441 m_stateRecordingVideo = state;
444 void Camera::setPendingOperation(
445 Commons::IWrtCamera::CameraPendingOperation pendingOperation, void* data)
447 LogDebug("Set pending operation callback invoked");
450 OpaquePrivateData* opaqueData = static_cast<OpaquePrivateData*> (data);
451 Assert(opaqueData->cameraPrivateData);
453 switch (opaqueData->eventTypeId) {
454 case BeginRecordingType:
456 static_cast<CameraPrivateData<Api::EventBeginRecordingSharedPtr>* > (
457 opaqueData->cameraPrivateData)
458 ->event->setPendingOperation(pendingOperation);
461 case CreatePreviewType:
463 static_cast<CameraPrivateData<Api::EventGetPreviewNodeSharedPtr>* > (
464 opaqueData->cameraPrivateData)
465 ->event->setPendingOperation(pendingOperation);
468 case TakePictureType:
470 static_cast<CameraPrivateData<Api::EventGetPreviewNodeSharedPtr>* > (
471 opaqueData->cameraPrivateData)
472 ->event->setPendingOperation(pendingOperation);