1 /*
2  * Copyright (C) Texas Instruments - http://www.ti.com/
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 /**
18 * @file CameraHal.cpp
19 *
20 * This file maps the Camera Hardware Interface to V4L2.
21 *
22 */
23 
24 #define LOG_TAG "CameraHAL"
25 
26 #include "CameraHal.h"
27 #include "ANativeWindowDisplayAdapter.h"
28 #include "TICameraParameters.h"
29 #include "CameraProperties.h"
30 #include <cutils/properties.h>
31 
32 #include <poll.h>
33 #include <math.h>
34 
35 namespace android {
36 
37 extern "C" CameraAdapter* CameraAdapter_Factory(size_t);
38 
39 /*****************************************************************************/
40 
41 ////Constant definitions and declarations
42 ////@todo Have a CameraProperties class to store these parameters as constants for every camera
43 ////       Currently, they are hard-coded
44 
45 const int CameraHal::NO_BUFFERS_PREVIEW = MAX_CAMERA_BUFFERS;
46 const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 2;
47 
48 const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 0;
49 const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;
50 
51 /******************************************************************************/
52 
53 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
54 
55 struct timeval CameraHal::mStartPreview;
56 struct timeval CameraHal::mStartFocus;
57 struct timeval CameraHal::mStartCapture;
58 
59 #endif
60 
orientation_cb(uint32_t orientation,uint32_t tilt,void * cookie)61 static void orientation_cb(uint32_t orientation, uint32_t tilt, void* cookie) {
62     CameraHal *camera = NULL;
63 
64     if (cookie) {
65         camera = (CameraHal*) cookie;
66         camera->onOrientationEvent(orientation, tilt);
67     }
68 
69 }
70 /*-------------Camera Hal Interface Method definitions STARTS here--------------------*/
71 
72 /**
73   Callback function to receive orientation events from SensorListener
74  */
onOrientationEvent(uint32_t orientation,uint32_t tilt)75 void CameraHal::onOrientationEvent(uint32_t orientation, uint32_t tilt) {
76     LOG_FUNCTION_NAME;
77 
78     if ( NULL != mCameraAdapter ) {
79         mCameraAdapter->onOrientationEvent(orientation, tilt);
80     }
81 
82     LOG_FUNCTION_NAME_EXIT;
83 }
84 
85 /**
86    @brief Set the notification and data callbacks
87 
88    @param[in] notify_cb Notify callback for notifying the app about events and errors
89    @param[in] data_cb   Buffer callback for sending the preview/raw frames to the app
90    @param[in] data_cb_timestamp Buffer callback for sending the video frames w/ timestamp
91    @param[in] user  Callback cookie
92    @return none
93 
94  */
setCallbacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)95 void CameraHal::setCallbacks(camera_notify_callback notify_cb,
96                             camera_data_callback data_cb,
97                             camera_data_timestamp_callback data_cb_timestamp,
98                             camera_request_memory get_memory,
99                             void *user)
100 {
101     LOG_FUNCTION_NAME;
102 
103     if ( NULL != mAppCallbackNotifier.get() )
104     {
105             mAppCallbackNotifier->setCallbacks(this,
106                                                 notify_cb,
107                                                 data_cb,
108                                                 data_cb_timestamp,
109                                                 get_memory,
110                                                 user);
111     }
112 
113     LOG_FUNCTION_NAME_EXIT;
114 }
115 
116 /**
117    @brief Enable a message, or set of messages.
118 
119    @param[in] msgtype Bitmask of the messages to enable (defined in include/ui/Camera.h)
120    @return none
121 
122  */
enableMsgType(int32_t msgType)123 void CameraHal::enableMsgType(int32_t msgType)
124 {
125     LOG_FUNCTION_NAME;
126 
127     if ( ( msgType & CAMERA_MSG_SHUTTER ) && ( !mShutterEnabled ) )
128         {
129         msgType &= ~CAMERA_MSG_SHUTTER;
130         }
131 
132     // ignoring enable focus message from camera service
133     // we will enable internally in autoFocus call
134     msgType &= ~(CAMERA_MSG_FOCUS | CAMERA_MSG_FOCUS_MOVE);
135 
136     {
137     Mutex::Autolock lock(mLock);
138     mMsgEnabled |= msgType;
139     }
140 
141     if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
142     {
143         if(mDisplayPaused)
144         {
145             CAMHAL_LOGDA("Preview currently paused...will enable preview callback when restarted");
146             msgType &= ~CAMERA_MSG_PREVIEW_FRAME;
147         }else
148         {
149             CAMHAL_LOGDA("Enabling Preview Callback");
150         }
151     }
152     else
153     {
154         CAMHAL_LOGDB("Preview callback not enabled %x", msgType);
155     }
156 
157 
158     ///Configure app callback notifier with the message callback required
159     mAppCallbackNotifier->enableMsgType (msgType);
160 
161     LOG_FUNCTION_NAME_EXIT;
162 }
163 
164 /**
165    @brief Disable a message, or set of messages.
166 
167    @param[in] msgtype Bitmask of the messages to disable (defined in include/ui/Camera.h)
168    @return none
169 
170  */
disableMsgType(int32_t msgType)171 void CameraHal::disableMsgType(int32_t msgType)
172 {
173     LOG_FUNCTION_NAME;
174 
175         {
176         Mutex::Autolock lock(mLock);
177         mMsgEnabled &= ~msgType;
178         }
179 
180     if( msgType & CAMERA_MSG_PREVIEW_FRAME)
181         {
182         CAMHAL_LOGDA("Disabling Preview Callback");
183         }
184 
185     ///Configure app callback notifier
186     mAppCallbackNotifier->disableMsgType (msgType);
187 
188     LOG_FUNCTION_NAME_EXIT;
189 }
190 
191 /**
192    @brief Query whether a message, or a set of messages, is enabled.
193 
194    Note that this is operates as an AND, if any of the messages queried are off, this will
195    return false.
196 
197    @param[in] msgtype Bitmask of the messages to query (defined in include/ui/Camera.h)
198    @return true If all message types are enabled
199           false If any message type
200 
201  */
msgTypeEnabled(int32_t msgType)202 int CameraHal::msgTypeEnabled(int32_t msgType)
203 {
204     LOG_FUNCTION_NAME;
205     Mutex::Autolock lock(mLock);
206     LOG_FUNCTION_NAME_EXIT;
207     return (mMsgEnabled & msgType);
208 }
209 
210 /**
211    @brief Set the camera parameters.
212 
213    @param[in] params Camera parameters to configure the camera
214    @return NO_ERROR
215    @todo Define error codes
216 
217  */
setParameters(const char * parameters)218 int CameraHal::setParameters(const char* parameters)
219 {
220 
221    LOG_FUNCTION_NAME;
222 
223     CameraParameters params;
224 
225     String8 str_params(parameters);
226     params.unflatten(str_params);
227 
228     LOG_FUNCTION_NAME_EXIT;
229 
230     return setParameters(params);
231 }
232 
233 /**
234    @brief Set the camera parameters.
235 
236    @param[in] params Camera parameters to configure the camera
237    @return NO_ERROR
238    @todo Define error codes
239 
240  */
setParameters(const CameraParameters & params)241 int CameraHal::setParameters(const CameraParameters& params)
242 {
243 
244    LOG_FUNCTION_NAME;
245 
246     int w, h;
247     int w_orig, h_orig;
248     int framerate,minframerate;
249     int maxFPS, minFPS;
250     const char *valstr = NULL;
251     int varint = 0;
252     status_t ret = NO_ERROR;
253     CameraParameters oldParams = mParameters;
254     // Needed for KEY_RECORDING_HINT
255     bool restartPreviewRequired = false;
256     bool updateRequired = false;
257     bool videoMode = false;
258 
259     {
260         Mutex::Autolock lock(mLock);
261 
262         ///Ensure that preview is not enabled when the below parameters are changed.
263         if(!previewEnabled())
264             {
265 
266             CAMHAL_LOGDB("PreviewFormat %s", params.getPreviewFormat());
267 
268             if ((valstr = params.getPreviewFormat()) != NULL) {
269                 if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS))) {
270                     mParameters.setPreviewFormat(valstr);
271                 } else {
272                     CAMHAL_LOGEB("Invalid preview format.Supported: %s",  mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
273                     return BAD_VALUE;
274                 }
275             }
276 
277             varint = params.getInt(TICameraParameters::KEY_VNF);
278             valstr = params.get(TICameraParameters::KEY_VNF);
279             if ( valstr != NULL ) {
280                 if ( ( varint == 0 ) || ( varint == 1 ) ) {
281                     CAMHAL_LOGDB("VNF set %s", valstr);
282                     mParameters.set(TICameraParameters::KEY_VNF, varint);
283                 } else {
284                     CAMHAL_LOGEB("ERROR: Invalid VNF: %s", valstr);
285                     return BAD_VALUE;
286                 }
287             }
288 
289             if ((valstr = params.get(CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL) {
290                 // make sure we support vstab...if we don't and application is trying to set
291                 // vstab then return an error
292                 if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
293                            CameraParameters::TRUE) == 0) {
294                     CAMHAL_LOGDB("VSTAB %s",valstr);
295                     mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION, valstr);
296                 } else if (strcmp(valstr, CameraParameters::TRUE) == 0) {
297                     CAMHAL_LOGEB("ERROR: Invalid VSTAB: %s", valstr);
298                     return BAD_VALUE;
299                 } else {
300                     mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION,
301                                     CameraParameters::FALSE);
302                 }
303             }
304 
305 
306 
307             if( (valstr = params.get(TICameraParameters::KEY_CAP_MODE)) != NULL)
308                 {
309                 CAMHAL_LOGDB("Capture mode set %s", valstr);
310                 mParameters.set(TICameraParameters::KEY_CAP_MODE, valstr);
311                 }
312 
313             if ((valstr = params.get(TICameraParameters::KEY_IPP)) != NULL) {
314                 if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES))) {
315                     CAMHAL_LOGDB("IPP mode set %s", valstr);
316                     mParameters.set(TICameraParameters::KEY_IPP, valstr);
317                 } else {
318                     CAMHAL_LOGEB("ERROR: Invalid IPP mode: %s", valstr);
319                     return BAD_VALUE;
320                 }
321             }
322 
323 #ifdef OMAP_ENHANCEMENT
324 
325             if((valstr = params.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL)
326                 {
327                 CAMHAL_LOGDB("Stereo 3D->2D Preview mode is %s", params.get(TICameraParameters::KEY_S3D2D_PREVIEW));
328                 mParameters.set(TICameraParameters::KEY_S3D2D_PREVIEW, valstr);
329                 }
330 
331             if((valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
332                 {
333                 CAMHAL_LOGDB("AutoConvergence mode is %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
334                 mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
335                 }
336 #endif
337 
338             }
339 
340             params.getPreviewSize(&w, &h);
341             if (w == -1 && h == -1) {
342                 CAMHAL_LOGEA("Unable to get preview size");
343                 return BAD_VALUE;
344               }
345 
346             int oldWidth, oldHeight;
347             mParameters.getPreviewSize(&oldWidth, &oldHeight);
348 
349 #ifdef OMAP_ENHANCEMENT
350 
351             int orientation =0;
352             if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
353                 {
354                 CAMHAL_LOGDB("Sensor Orientation is set to %s", params.get(TICameraParameters::KEY_SENSOR_ORIENTATION));
355                 mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
356                 orientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
357                 }
358 
359             if(orientation ==90 || orientation ==270)
360            {
361               if ( !isResolutionValid(h,w, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
362                {
363                 CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
364                 return BAD_VALUE;
365                }
366               else
367               {
368                 mParameters.setPreviewSize(w, h);
369                 mVideoWidth = w;
370                 mVideoHeight = h;
371                }
372            }
373            else
374            {
375             if ( !isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
376                 {
377                 CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
378                 return BAD_VALUE;
379                 }
380             else
381                 {
382                 mParameters.setPreviewSize(w, h);
383                 }
384            }
385 
386 
387 #else
388 
389         if ( !isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES))) {
390             CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
391             return BAD_VALUE;
392         } else {
393             mParameters.setPreviewSize(w, h);
394         }
395 
396 #endif
397 
398         if ( ( oldWidth != w ) || ( oldHeight != h ) ) {
399             restartPreviewRequired |= true;
400         }
401 
402         CAMHAL_LOGDB("PreviewResolution by App %d x %d", w, h);
403 
404         // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
405         valstr = params.get(CameraParameters::KEY_RECORDING_HINT);
406         if(valstr != NULL)
407             {
408             if(strcmp(valstr, CameraParameters::TRUE) == 0)
409                 {
410                 CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
411                 mParameters.set(CameraParameters::KEY_RECORDING_HINT, valstr);
412                 videoMode = true;
413                 int w, h;
414 
415                 params.getPreviewSize(&w, &h);
416                 CAMHAL_LOGVB("%s Preview Width=%d Height=%d\n", __FUNCTION__, w, h);
417                 //HACK FOR MMS
418                 mVideoWidth = w;
419                 mVideoHeight = h;
420                 CAMHAL_LOGVB("%s Video Width=%d Height=%d\n", __FUNCTION__, mVideoWidth, mVideoHeight);
421 
422                 setPreferredPreviewRes(w, h);
423                 mParameters.getPreviewSize(&w, &h);
424                 CAMHAL_LOGVB("%s Preview Width=%d Height=%d\n", __FUNCTION__, w, h);
425                 //Avoid restarting preview for MMS HACK
426                 if ((w != mVideoWidth) && (h != mVideoHeight))
427                     {
428                     restartPreviewRequired = false;
429                     }
430 
431                 restartPreviewRequired |= setVideoModeParameters(params);
432                 }
433             else if(strcmp(valstr, CameraParameters::FALSE) == 0)
434                 {
435                 CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
436                 mParameters.set(CameraParameters::KEY_RECORDING_HINT, valstr);
437                 restartPreviewRequired |= resetVideoModeParameters();
438                 params.getPreviewSize(&mVideoWidth, &mVideoHeight);
439                 }
440             else
441                 {
442                 CAMHAL_LOGEA("Invalid RECORDING_HINT");
443                 return BAD_VALUE;
444                 }
445             }
446         else
447             {
448             // This check is required in following case.
449             // If VideoRecording activity sets KEY_RECORDING_HINT to TRUE and
450             // ImageCapture activity doesnot set KEY_RECORDING_HINT to FALSE (i.e. simply NULL),
451             // then Video Mode parameters may remain present in ImageCapture activity as well.
452             CAMHAL_LOGDA("Recording Hint is set to NULL");
453             mParameters.set(CameraParameters::KEY_RECORDING_HINT, "");
454             restartPreviewRequired |= resetVideoModeParameters();
455             params.getPreviewSize(&mVideoWidth, &mVideoHeight);
456             }
457 
458         if ((valstr = params.get(CameraParameters::KEY_FOCUS_MODE)) != NULL) {
459             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES))) {
460                 CAMHAL_LOGDB("Focus mode set %s", valstr);
461 
462                 // we need to take a decision on the capture mode based on whether CAF picture or
463                 // video is chosen so the behavior of each is consistent to the application
464                 if(strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0){
465                     restartPreviewRequired |= resetVideoModeParameters();
466                 } else if (strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0){
467                     restartPreviewRequired |= setVideoModeParameters(params);
468                 }
469 
470                 mParameters.set(CameraParameters::KEY_FOCUS_MODE, valstr);
471              } else {
472                 CAMHAL_LOGEB("ERROR: Invalid FOCUS mode = %s", valstr);
473                 return BAD_VALUE;
474              }
475         }
476 
477         ///Below parameters can be changed when the preview is running
478         if ( (valstr = params.getPictureFormat()) != NULL ) {
479             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS))) {
480                 mParameters.setPictureFormat(valstr);
481             } else {
482                 CAMHAL_LOGEB("ERROR: Invalid picture format: %s",valstr);
483                 return BAD_VALUE;
484             }
485         }
486 
487         params.getPictureSize(&w, &h);
488         if ( isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES))) {
489             mParameters.setPictureSize(w, h);
490         } else {
491             CAMHAL_LOGEB("ERROR: Invalid picture resolution %dx%d", w, h);
492             return BAD_VALUE;
493         }
494 
495         CAMHAL_LOGDB("Picture Size by App %d x %d", w, h);
496 
497 #ifdef OMAP_ENHANCEMENT
498 
499         if ((valstr = params.get(TICameraParameters::KEY_BURST)) != NULL) {
500             if (params.getInt(TICameraParameters::KEY_BURST) >=0) {
501                 CAMHAL_LOGDB("Burst set %s", valstr);
502                 mParameters.set(TICameraParameters::KEY_BURST, valstr);
503             } else {
504                 CAMHAL_LOGEB("ERROR: Invalid Burst value: %s",valstr);
505                 return BAD_VALUE;
506             }
507         }
508 
509 #endif
510 
511         framerate = params.getPreviewFrameRate();
512         valstr = params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
513         CAMHAL_LOGDB("FRAMERATE %d", framerate);
514 
515         CAMHAL_LOGVB("Passed FRR: %s, Supported FRR %s", valstr
516                         , mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
517         CAMHAL_LOGVB("Passed FR: %d, Supported FR %s", framerate
518                         , mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
519 
520 
521         //Perform parameter validation
522         if(!isParameterValid(valstr
523                         , mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED))
524                         || !isParameterValid(framerate,
525                                       mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES)))
526         {
527             CAMHAL_LOGEA("Invalid frame rate range or frame rate");
528             return BAD_VALUE;
529         }
530 
531         // Variable framerate ranges have higher priority over
532         // deprecated constant FPS. "KEY_PREVIEW_FPS_RANGE" should
533         // be cleared by the client in order for constant FPS to get
534         // applied.
535         if ( strcmp(valstr, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE))  != 0)
536           {
537             // APP wants to set FPS range
538             //Set framerate = MAXFPS
539             CAMHAL_LOGDA("APP IS CHANGING FRAME RATE RANGE");
540             params.getPreviewFpsRange(&minFPS, &maxFPS);
541 
542             if ( ( 0 > minFPS ) || ( 0 > maxFPS ) )
543               {
544                 CAMHAL_LOGEA("ERROR: FPS Range is negative!");
545                 return BAD_VALUE;
546               }
547 
548             framerate = maxFPS /CameraHal::VFR_SCALE;
549 
550           }
551         else
552           {
553               if ( framerate != atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)) )
554               {
555 
556                 selectFPSRange(framerate, &minFPS, &maxFPS);
557                 CAMHAL_LOGDB("Select FPS Range %d %d", minFPS, maxFPS);
558               }
559               else
560                 {
561                     if (videoMode) {
562                         valstr = mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_VIDEO);
563                         CameraParameters temp;
564                         temp.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
565                         temp.getPreviewFpsRange(&minFPS, &maxFPS);
566                     }
567                     else {
568                         valstr = mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_IMAGE);
569                         CameraParameters temp;
570                         temp.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
571                         temp.getPreviewFpsRange(&minFPS, &maxFPS);
572                     }
573 
574                     framerate = maxFPS / CameraHal::VFR_SCALE;
575                 }
576 
577           }
578 
579         CAMHAL_LOGDB("FPS Range = %s", valstr);
580         CAMHAL_LOGDB("DEFAULT FPS Range = %s", mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
581 
582         minFPS /= CameraHal::VFR_SCALE;
583         maxFPS /= CameraHal::VFR_SCALE;
584 
585         if ( ( 0 == minFPS ) || ( 0 == maxFPS ) )
586           {
587             CAMHAL_LOGEA("ERROR: FPS Range is invalid!");
588             return BAD_VALUE;
589           }
590 
591         if ( maxFPS < minFPS )
592           {
593             CAMHAL_LOGEA("ERROR: Max FPS is smaller than Min FPS!");
594             return BAD_VALUE;
595           }
596         CAMHAL_LOGDB("SET FRAMERATE %d", framerate);
597         mParameters.setPreviewFrameRate(framerate);
598         mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, params.get(CameraParameters::KEY_PREVIEW_FPS_RANGE));
599 
600         CAMHAL_LOGDB("FPS Range [%d, %d]", minFPS, maxFPS);
601         mParameters.set(TICameraParameters::KEY_MINFRAMERATE, minFPS);
602         mParameters.set(TICameraParameters::KEY_MAXFRAMERATE, maxFPS);
603 
604         if( ( valstr = params.get(TICameraParameters::KEY_GBCE) ) != NULL )
605             {
606             CAMHAL_LOGDB("GBCE Value = %s", valstr);
607             mParameters.set(TICameraParameters::KEY_GBCE, valstr);
608             }
609 
610         if( ( valstr = params.get(TICameraParameters::KEY_GLBCE) ) != NULL )
611             {
612             CAMHAL_LOGDB("GLBCE Value = %s", valstr);
613             mParameters.set(TICameraParameters::KEY_GLBCE, valstr);
614             }
615 
616 #ifdef OMAP_ENHANCEMENT
617 
618         ///Update the current parameter set
619         if( (valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE)) != NULL)
620             {
621             CAMHAL_LOGDB("AutoConvergence Mode is set = %s", params.get(TICameraParameters::KEY_AUTOCONVERGENCE));
622             mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE, valstr);
623             }
624 
625         if( (valstr = params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES)) !=NULL )
626             {
627             CAMHAL_LOGDB("ManualConvergence Value = %s", params.get(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES));
628             mParameters.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, valstr);
629             }
630 
631         if ((valstr = params.get(TICameraParameters::KEY_EXPOSURE_MODE)) != NULL) {
632             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES))) {
633                 CAMHAL_LOGDB("Exposure set = %s", valstr);
634                 mParameters.set(TICameraParameters::KEY_EXPOSURE_MODE, valstr);
635             } else {
636                 CAMHAL_LOGEB("ERROR: Invalid Exposure  = %s", valstr);
637                 return BAD_VALUE;
638             }
639         }
640 
641 #endif
642 
643         if ((valstr = params.get(CameraParameters::KEY_WHITE_BALANCE)) != NULL) {
644            if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE))) {
645                CAMHAL_LOGDB("White balance set %s", valstr);
646                mParameters.set(CameraParameters::KEY_WHITE_BALANCE, valstr);
647             } else {
648                CAMHAL_LOGEB("ERROR: Invalid white balance  = %s", valstr);
649                return BAD_VALUE;
650             }
651         }
652 
653 #ifdef OMAP_ENHANCEMENT
654 
655         if ((valstr = params.get(TICameraParameters::KEY_CONTRAST)) != NULL) {
656             if (params.getInt(TICameraParameters::KEY_CONTRAST) >= 0 ) {
657                 CAMHAL_LOGDB("Contrast set %s", valstr);
658                 mParameters.set(TICameraParameters::KEY_CONTRAST, valstr);
659             } else {
660                 CAMHAL_LOGEB("ERROR: Invalid Contrast  = %s", valstr);
661                 return BAD_VALUE;
662             }
663         }
664 
665         if ((valstr =params.get(TICameraParameters::KEY_SHARPNESS)) != NULL) {
666             if (params.getInt(TICameraParameters::KEY_SHARPNESS) >= 0 ) {
667                 CAMHAL_LOGDB("Sharpness set %s", valstr);
668                 mParameters.set(TICameraParameters::KEY_SHARPNESS, valstr);
669             } else {
670                 CAMHAL_LOGEB("ERROR: Invalid Sharpness = %s", valstr);
671                 return BAD_VALUE;
672             }
673         }
674 
675         if ((valstr = params.get(TICameraParameters::KEY_SATURATION)) != NULL) {
676             if (params.getInt(TICameraParameters::KEY_SATURATION) >= 0 ) {
677                 CAMHAL_LOGDB("Saturation set %s", valstr);
678                 mParameters.set(TICameraParameters::KEY_SATURATION, valstr);
679              } else {
680                 CAMHAL_LOGEB("ERROR: Invalid Saturation = %s", valstr);
681                 return BAD_VALUE;
682             }
683         }
684 
685         if ((valstr = params.get(TICameraParameters::KEY_BRIGHTNESS)) != NULL) {
686             if (params.getInt(TICameraParameters::KEY_BRIGHTNESS) >= 0 ) {
687                 CAMHAL_LOGDB("Brightness set %s", valstr);
688                 mParameters.set(TICameraParameters::KEY_BRIGHTNESS, valstr);
689             } else {
690                 CAMHAL_LOGEB("ERROR: Invalid Brightness = %s", valstr);
691                 return BAD_VALUE;
692             }
693          }
694 
695 #endif
696 
697         if ((valstr = params.get(CameraParameters::KEY_ANTIBANDING)) != NULL) {
698             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING))) {
699                 CAMHAL_LOGDB("Antibanding set %s", valstr);
700                 mParameters.set(CameraParameters::KEY_ANTIBANDING, valstr);
701              } else {
702                 CAMHAL_LOGEB("ERROR: Invalid Antibanding = %s", valstr);
703                 return BAD_VALUE;
704              }
705          }
706 
707 #ifdef OMAP_ENHANCEMENT
708 
709         if ((valstr = params.get(TICameraParameters::KEY_ISO)) != NULL) {
710             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES))) {
711                 CAMHAL_LOGDB("ISO set %s", valstr);
712                 mParameters.set(TICameraParameters::KEY_ISO, valstr);
713             } else {
714                 CAMHAL_LOGEB("ERROR: Invalid ISO = %s", valstr);
715                 return BAD_VALUE;
716             }
717         }
718 
719 #endif
720 
721         if( (valstr = params.get(CameraParameters::KEY_FOCUS_AREAS)) != NULL )
722             {
723             CAMHAL_LOGDB("Focus areas position set %s",valstr);
724             mParameters.set(CameraParameters::KEY_FOCUS_AREAS, valstr);
725             }
726 
727 #ifdef OMAP_ENHANCEMENT
728 
729         if( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
730             {
731             CAMHAL_LOGDB("Measurements set to %s", params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE));
732             mParameters.set(TICameraParameters::KEY_MEASUREMENT_ENABLE, valstr);
733 
734             if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_ENABLE) == 0)
735                 {
736                 mMeasurementEnabled = true;
737                 }
738             else if (strcmp(valstr, (const char *) TICameraParameters::MEASUREMENT_DISABLE) == 0)
739                 {
740                 mMeasurementEnabled = false;
741                 }
742             else
743                 {
744                 mMeasurementEnabled = false;
745                 }
746 
747             }
748 
749 #endif
750 
751         if( (valstr = params.get(CameraParameters::KEY_EXPOSURE_COMPENSATION)) != NULL)
752             {
753             CAMHAL_LOGDB("Exposure compensation set %s", valstr);
754             mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, valstr);
755             }
756 
757         if ((valstr = params.get(CameraParameters::KEY_SCENE_MODE)) != NULL) {
758             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES))) {
759                 CAMHAL_LOGDB("Scene mode set %s", valstr);
760                 doesSetParameterNeedUpdate(valstr,
761                                            mParameters.get(CameraParameters::KEY_SCENE_MODE),
762                                            updateRequired);
763                 mParameters.set(CameraParameters::KEY_SCENE_MODE, valstr);
764             } else {
765                 CAMHAL_LOGEB("ERROR: Invalid Scene mode = %s", valstr);
766                 return BAD_VALUE;
767             }
768         }
769 
770         if ((valstr = params.get(CameraParameters::KEY_FLASH_MODE)) != NULL) {
771             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES))) {
772                 CAMHAL_LOGDB("Flash mode set %s", valstr);
773                 mParameters.set(CameraParameters::KEY_FLASH_MODE, valstr);
774             } else {
775                 CAMHAL_LOGEB("ERROR: Invalid Flash mode = %s", valstr);
776                 return BAD_VALUE;
777             }
778         }
779 
780         if ((valstr = params.get(CameraParameters::KEY_EFFECT)) != NULL) {
781             if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS))) {
782                 CAMHAL_LOGDB("Effect set %s", valstr);
783                 mParameters.set(CameraParameters::KEY_EFFECT, valstr);
784              } else {
785                 CAMHAL_LOGEB("ERROR: Invalid Effect = %s", valstr);
786                 return BAD_VALUE;
787              }
788         }
789 
790         varint = params.getInt(CameraParameters::KEY_ROTATION);
791         if( varint >=0 )
792             {
793             CAMHAL_LOGDB("Rotation set %d", varint);
794             mParameters.set(CameraParameters::KEY_ROTATION, varint);
795             }
796 
797         varint = params.getInt(CameraParameters::KEY_JPEG_QUALITY);
798         if( varint >= 0 )
799             {
800             CAMHAL_LOGDB("Jpeg quality set %d", varint);
801             mParameters.set(CameraParameters::KEY_JPEG_QUALITY, varint);
802             }
803 
804         varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
805         if( varint >=0 )
806             {
807             CAMHAL_LOGDB("Thumbnail width set %d", varint);
808             mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, varint);
809             }
810 
811         varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
812         if( varint >=0 )
813             {
814             CAMHAL_LOGDB("Thumbnail width set %d", varint);
815             mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, varint);
816             }
817 
818         varint = params.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
819         if( varint >=0 )
820             {
821             CAMHAL_LOGDB("Thumbnail quality set %d", varint);
822             mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, varint);
823             }
824 
825         if( (valstr = params.get(CameraParameters::KEY_GPS_LATITUDE)) != NULL )
826             {
827             CAMHAL_LOGDB("GPS latitude set %s", valstr);
828             mParameters.set(CameraParameters::KEY_GPS_LATITUDE, valstr);
829             }else{
830                 mParameters.remove(CameraParameters::KEY_GPS_LATITUDE);
831             }
832 
833         if( (valstr = params.get(CameraParameters::KEY_GPS_LONGITUDE)) != NULL )
834             {
835             CAMHAL_LOGDB("GPS longitude set %s", valstr);
836             mParameters.set(CameraParameters::KEY_GPS_LONGITUDE, valstr);
837             }else{
838                 mParameters.remove(CameraParameters::KEY_GPS_LONGITUDE);
839             }
840 
841         if( (valstr = params.get(CameraParameters::KEY_GPS_ALTITUDE)) != NULL )
842             {
843             CAMHAL_LOGDB("GPS altitude set %s", valstr);
844             mParameters.set(CameraParameters::KEY_GPS_ALTITUDE, valstr);
845             }else{
846                 mParameters.remove(CameraParameters::KEY_GPS_ALTITUDE);
847             }
848 
849         if( (valstr = params.get(CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
850             {
851             CAMHAL_LOGDB("GPS timestamp set %s", valstr);
852             mParameters.set(CameraParameters::KEY_GPS_TIMESTAMP, valstr);
853             }else{
854                 mParameters.remove(CameraParameters::KEY_GPS_TIMESTAMP);
855             }
856 
857         if( (valstr = params.get(TICameraParameters::KEY_GPS_DATESTAMP)) != NULL )
858             {
859             CAMHAL_LOGDB("GPS datestamp set %s", valstr);
860             mParameters.set(TICameraParameters::KEY_GPS_DATESTAMP, valstr);
861             }else{
862                 mParameters.remove(TICameraParameters::KEY_GPS_DATESTAMP);
863             }
864 
865         if( (valstr = params.get(CameraParameters::KEY_GPS_PROCESSING_METHOD)) != NULL )
866             {
867             CAMHAL_LOGDB("GPS processing method set %s", valstr);
868             mParameters.set(CameraParameters::KEY_GPS_PROCESSING_METHOD, valstr);
869             }else{
870                 mParameters.remove(CameraParameters::KEY_GPS_PROCESSING_METHOD);
871             }
872 
873         if( (valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM )) != NULL )
874             {
875             CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
876             mParameters.set(TICameraParameters::KEY_GPS_MAPDATUM, valstr);
877             }else{
878                 mParameters.remove(TICameraParameters::KEY_GPS_MAPDATUM);
879             }
880 
881         if( (valstr = params.get(TICameraParameters::KEY_GPS_VERSION)) != NULL )
882             {
883             CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
884             mParameters.set(TICameraParameters::KEY_GPS_VERSION, valstr);
885             }else{
886                 mParameters.remove(TICameraParameters::KEY_GPS_VERSION);
887             }
888 
889         if( (valstr = params.get(TICameraParameters::KEY_EXIF_MODEL)) != NULL )
890             {
891             CAMHAL_LOGDB("EXIF Model set %s", valstr);
892             mParameters.set(TICameraParameters::KEY_EXIF_MODEL, valstr);
893             }
894 
895         if( (valstr = params.get(TICameraParameters::KEY_EXIF_MAKE)) != NULL )
896             {
897             CAMHAL_LOGDB("EXIF Make set %s", valstr);
898             mParameters.set(TICameraParameters::KEY_EXIF_MAKE, valstr);
899             }
900 
901 #ifdef OMAP_ENHANCEMENT
902 
903         if( (valstr = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL )
904             {
905             CAMHAL_LOGDB("Exposure Bracketing set %s", params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE));
906             mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valstr);
907             }
908         else
909             {
910             mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
911             }
912 
913 #endif
914 
915         valstr = params.get(CameraParameters::KEY_ZOOM);
916         varint = params.getInt(CameraParameters::KEY_ZOOM);
917         if ( valstr != NULL ) {
918             if ( ( varint >= 0 ) && ( varint <= mMaxZoomSupported ) ) {
919                 CAMHAL_LOGDB("Zoom set %s", valstr);
920                 doesSetParameterNeedUpdate(valstr,
921                                            mParameters.get(CameraParameters::KEY_ZOOM),
922                                            updateRequired);
923                 mParameters.set(CameraParameters::KEY_ZOOM, valstr);
924              } else {
925                 CAMHAL_LOGEB("ERROR: Invalid Zoom: %s", valstr);
926                 return BAD_VALUE;
927             }
928         }
929 
930         if( (valstr = params.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
931           {
932             CAMHAL_LOGDB("Auto Exposure Lock set %s", valstr);
933             doesSetParameterNeedUpdate(valstr,
934                                        mParameters.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK),
935                                        updateRequired);
936             mParameters.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
937           }
938 
939         if( (valstr = params.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
940           {
941             CAMHAL_LOGDB("Auto WhiteBalance Lock set %s", valstr);
942             doesSetParameterNeedUpdate(valstr,
943                                        mParameters.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK),
944                                        updateRequired);
945             mParameters.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
946           }
947         if( (valstr = params.get(CameraParameters::KEY_METERING_AREAS)) != NULL )
948             {
949             CAMHAL_LOGDB("Metering areas position set %s", valstr);
950             mParameters.set(CameraParameters::KEY_METERING_AREAS, valstr);
951             }
952 
953         // Only send parameters to adapter if preview is already
954         // enabled or doesSetParameterNeedUpdate says so. Initial setParameters to camera adapter,
955         // will be called in startPreview()
956         // TODO(XXX): Need to identify other parameters that need update from camera adapter
957         if ( (NULL != mCameraAdapter) && (mPreviewEnabled || updateRequired) ) {
958             ret |= mCameraAdapter->setParameters(mParameters);
959         }
960 
961 #ifdef OMAP_ENHANCEMENT
962 
963         if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS) )
964             {
965             int posBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS);
966             if ( 0 < posBracketRange )
967                 {
968                 mBracketRangePositive = posBracketRange;
969                 }
970             }
971         CAMHAL_LOGDB("Positive bracketing range %d", mBracketRangePositive);
972 
973 
974         if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG) )
975             {
976             int negBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG);
977             if ( 0 < negBracketRange )
978                 {
979                 mBracketRangeNegative = negBracketRange;
980                 }
981             }
982         CAMHAL_LOGDB("Negative bracketing range %d", mBracketRangeNegative);
983 
984         if( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL) &&
985             ( strcmp(valstr, TICameraParameters::BRACKET_ENABLE) == 0 ))
986             {
987             if ( !mBracketingEnabled )
988                 {
989                 CAMHAL_LOGDA("Enabling bracketing");
990                 mBracketingEnabled = true;
991 
992                 //Wait for AF events to enable bracketing
993                 if ( NULL != mCameraAdapter )
994                     {
995                     setEventProvider( CameraHalEvent::ALL_EVENTS, mCameraAdapter );
996                     }
997                 }
998             else
999                 {
1000                 CAMHAL_LOGDA("Bracketing already enabled");
1001                 }
1002             }
1003         else if ( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL ) &&
1004             ( strcmp(valstr, TICameraParameters::BRACKET_DISABLE) == 0 ))
1005             {
1006             CAMHAL_LOGDA("Disabling bracketing");
1007 
1008             mBracketingEnabled = false;
1009             stopImageBracketing();
1010 
1011             //Remove AF events subscription
1012             if ( NULL != mEventProvider )
1013                 {
1014                 mEventProvider->disableEventNotification( CameraHalEvent::ALL_EVENTS );
1015                 delete mEventProvider;
1016                 mEventProvider = NULL;
1017                 }
1018 
1019             }
1020 
1021         if( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
1022             ( strcmp(valstr, TICameraParameters::SHUTTER_ENABLE) == 0 ))
1023             {
1024             CAMHAL_LOGDA("Enabling shutter sound");
1025 
1026             mShutterEnabled = true;
1027             mMsgEnabled |= CAMERA_MSG_SHUTTER;
1028             mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
1029             }
1030         else if ( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
1031             ( strcmp(valstr, TICameraParameters::SHUTTER_DISABLE) == 0 ))
1032             {
1033             CAMHAL_LOGDA("Disabling shutter sound");
1034 
1035             mShutterEnabled = false;
1036             mMsgEnabled &= ~CAMERA_MSG_SHUTTER;
1037             mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
1038             }
1039 
1040 #endif
1041 
1042     }
1043 
1044     //On fail restore old parameters
1045     if ( NO_ERROR != ret ) {
1046         mParameters = oldParams;
1047     }
1048 
1049     // Restart Preview if needed by KEY_RECODING_HINT only if preview is already running.
1050     // If preview is not started yet, Video Mode parameters will take effect on next startPreview()
1051     if (restartPreviewRequired && previewEnabled() && !mRecordingEnabled) {
1052         CAMHAL_LOGDA("Restarting Preview");
1053         ret = restartPreview();
1054     } else if (restartPreviewRequired && !previewEnabled() &&
1055                 mDisplayPaused && !mRecordingEnabled) {
1056         CAMHAL_LOGDA("Stopping Preview");
1057         forceStopPreview();
1058     }
1059 
1060     if (ret != NO_ERROR)
1061         {
1062         CAMHAL_LOGEA("Failed to restart Preview");
1063         return ret;
1064         }
1065 
1066     LOG_FUNCTION_NAME_EXIT;
1067 
1068     return ret;
1069 }
1070 
allocPreviewBufs(int width,int height,const char * previewFormat,unsigned int buffercount,unsigned int & max_queueable)1071 status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat,
1072                                         unsigned int buffercount, unsigned int &max_queueable)
1073 {
1074     status_t ret = NO_ERROR;
1075 
1076     LOG_FUNCTION_NAME;
1077 
1078     if(mDisplayAdapter.get() == NULL)
1079     {
1080         // Memory allocation of preview buffers is now placed in gralloc
1081         // CameraHal should not allocate preview buffers without DisplayAdapter
1082         return NO_MEMORY;
1083     }
1084 
1085     if(!mPreviewBufs)
1086     {
1087         ///@todo Pluralise the name of this method to allocateBuffers
1088         mPreviewLength = 0;
1089         mPreviewBufs = (int32_t *) mDisplayAdapter->allocateBuffer(width, height,
1090                                                                     previewFormat,
1091                                                                     mPreviewLength,
1092                                                                     buffercount);
1093 
1094 	if (NULL == mPreviewBufs ) {
1095             CAMHAL_LOGEA("Couldn't allocate preview buffers");
1096             return NO_MEMORY;
1097          }
1098 
1099         mPreviewOffsets = (uint32_t *) mDisplayAdapter->getOffsets();
1100         if ( NULL == mPreviewOffsets ) {
1101             CAMHAL_LOGEA("Buffer mapping failed");
1102             return BAD_VALUE;
1103          }
1104 
1105         mPreviewFd = mDisplayAdapter->getFd();
1106         if ( -1 == mPreviewFd ) {
1107             CAMHAL_LOGEA("Invalid handle");
1108             return BAD_VALUE;
1109           }
1110 
1111         mBufProvider = (BufferProvider*) mDisplayAdapter.get();
1112 
1113         ret = mDisplayAdapter->maxQueueableBuffers(max_queueable);
1114         if (ret != NO_ERROR) {
1115             return ret;
1116          }
1117 
1118     }
1119 
1120     LOG_FUNCTION_NAME_EXIT;
1121 
1122     return ret;
1123 
1124 }
1125 
freePreviewBufs()1126 status_t CameraHal::freePreviewBufs()
1127 {
1128     status_t ret = NO_ERROR;
1129     LOG_FUNCTION_NAME;
1130 
1131     CAMHAL_LOGDB("mPreviewBufs = 0x%x", (unsigned int)mPreviewBufs);
1132     if(mPreviewBufs)
1133         {
1134         ///@todo Pluralise the name of this method to freeBuffers
1135         ret = mBufProvider->freeBuffer(mPreviewBufs);
1136         mPreviewBufs = NULL;
1137         LOG_FUNCTION_NAME_EXIT;
1138         return ret;
1139         }
1140     LOG_FUNCTION_NAME_EXIT;
1141     return ret;
1142 }
1143 
1144 
allocPreviewDataBufs(size_t size,size_t bufferCount)1145 status_t CameraHal::allocPreviewDataBufs(size_t size, size_t bufferCount)
1146 {
1147     status_t ret = NO_ERROR;
1148     int bytes;
1149 
1150     LOG_FUNCTION_NAME;
1151 
1152     bytes = size;
1153 
1154     if ( NO_ERROR == ret )
1155         {
1156         if( NULL != mPreviewDataBufs )
1157             {
1158             ret = freePreviewDataBufs();
1159             }
1160         }
1161 
1162     if ( NO_ERROR == ret )
1163         {
1164         bytes = ((bytes+4095)/4096)*4096;
1165         mPreviewDataBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, NULL, bytes, bufferCount);
1166 
1167         CAMHAL_LOGDB("Size of Preview data buffer = %d", bytes);
1168         if( NULL == mPreviewDataBufs )
1169             {
1170             CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
1171             ret = -NO_MEMORY;
1172             }
1173         else
1174             {
1175             bytes = size;
1176             }
1177         }
1178 
1179     if ( NO_ERROR == ret )
1180         {
1181         mPreviewDataFd = mMemoryManager->getFd();
1182         mPreviewDataLength = bytes;
1183         mPreviewDataOffsets = mMemoryManager->getOffsets();
1184         }
1185     else
1186         {
1187         mPreviewDataFd = -1;
1188         mPreviewDataLength = 0;
1189         mPreviewDataOffsets = NULL;
1190         }
1191 
1192     LOG_FUNCTION_NAME;
1193 
1194     return ret;
1195 }
1196 
freePreviewDataBufs()1197 status_t CameraHal::freePreviewDataBufs()
1198 {
1199     status_t ret = NO_ERROR;
1200 
1201     LOG_FUNCTION_NAME;
1202 
1203     if ( NO_ERROR == ret )
1204         {
1205 
1206         if( NULL != mPreviewDataBufs )
1207             {
1208 
1209             ///@todo Pluralise the name of this method to freeBuffers
1210             ret = mMemoryManager->freeBuffer(mPreviewDataBufs);
1211             mPreviewDataBufs = NULL;
1212 
1213             }
1214         }
1215 
1216     LOG_FUNCTION_NAME_EXIT;
1217 
1218     return ret;
1219 }
1220 
allocImageBufs(unsigned int width,unsigned int height,size_t size,const char * previewFormat,unsigned int bufferCount)1221 status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size, const char* previewFormat, unsigned int bufferCount)
1222 {
1223     status_t ret = NO_ERROR;
1224     int bytes;
1225 
1226     LOG_FUNCTION_NAME;
1227 
1228     bytes = size;
1229 
1230     // allocate image buffers only if not already allocated
1231     if(NULL != mImageBufs) {
1232         return NO_ERROR;
1233     }
1234 
1235     if ( NO_ERROR == ret )
1236         {
1237         bytes = ((bytes+4095)/4096)*4096;
1238         mImageBufs = (int32_t *)mMemoryManager->allocateBuffer(0, 0, previewFormat, bytes, bufferCount);
1239 
1240         CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
1241         if( NULL == mImageBufs )
1242             {
1243             CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
1244             ret = -NO_MEMORY;
1245             }
1246         else
1247             {
1248             bytes = size;
1249             }
1250         }
1251 
1252     if ( NO_ERROR == ret )
1253         {
1254         mImageFd = mMemoryManager->getFd();
1255         mImageLength = bytes;
1256         mImageOffsets = mMemoryManager->getOffsets();
1257         }
1258     else
1259         {
1260         mImageFd = -1;
1261         mImageLength = 0;
1262         mImageOffsets = NULL;
1263         }
1264 
1265     LOG_FUNCTION_NAME;
1266 
1267     return ret;
1268 }
1269 
allocVideoBufs(uint32_t width,uint32_t height,uint32_t bufferCount)1270 status_t CameraHal::allocVideoBufs(uint32_t width, uint32_t height, uint32_t bufferCount)
1271 {
1272   status_t ret = NO_ERROR;
1273   LOG_FUNCTION_NAME;
1274 
1275   if( NULL != mVideoBufs ){
1276     ret = freeVideoBufs(mVideoBufs);
1277     mVideoBufs = NULL;
1278   }
1279 
1280   if ( NO_ERROR == ret ){
1281     int32_t stride;
1282     buffer_handle_t *bufsArr = new buffer_handle_t [bufferCount];
1283 
1284     if (bufsArr != NULL){
1285       for (int i = 0; i< bufferCount; i++){
1286         GraphicBufferAllocator &GrallocAlloc = GraphicBufferAllocator::get();
1287         buffer_handle_t buf;
1288         ret = GrallocAlloc.alloc(width, height, HAL_PIXEL_FORMAT_NV12, CAMHAL_GRALLOC_USAGE, &buf, &stride);
1289         if (ret != NO_ERROR){
1290           CAMHAL_LOGEA("Couldn't allocate video buffers using Gralloc");
1291           ret = -NO_MEMORY;
1292           for (int j=0; j< i; j++){
1293             buf = (buffer_handle_t)bufsArr[j];
1294             CAMHAL_LOGEB("Freeing Gralloc Buffer 0x%x", buf);
1295             GrallocAlloc.free(buf);
1296           }
1297           delete [] bufsArr;
1298           goto exit;
1299         }
1300         bufsArr[i] = buf;
1301         CAMHAL_LOGVB("*** Gralloc Handle =0x%x ***", buf);
1302       }
1303 
1304       mVideoBufs = (int32_t *)bufsArr;
1305     }
1306     else{
1307       CAMHAL_LOGEA("Couldn't allocate video buffers ");
1308       ret = -NO_MEMORY;
1309     }
1310   }
1311 
1312  exit:
1313   LOG_FUNCTION_NAME;
1314 
1315   return ret;
1316 }
1317 
endImageCapture(void * userData)1318 void endImageCapture( void *userData)
1319 {
1320     LOG_FUNCTION_NAME;
1321 
1322     if ( NULL != userData )
1323         {
1324         CameraHal *c = reinterpret_cast<CameraHal *>(userData);
1325         c->signalEndImageCapture();
1326         }
1327 
1328     LOG_FUNCTION_NAME_EXIT;
1329 }
1330 
releaseImageBuffers(void * userData)1331 void releaseImageBuffers(void *userData)
1332 {
1333     LOG_FUNCTION_NAME;
1334 
1335     if (NULL != userData) {
1336         CameraHal *c = reinterpret_cast<CameraHal *>(userData);
1337         c->freeImageBufs();
1338     }
1339 
1340     LOG_FUNCTION_NAME_EXIT;
1341 }
1342 
signalEndImageCapture()1343 status_t CameraHal::signalEndImageCapture()
1344 {
1345     status_t ret = NO_ERROR;
1346     int w,h;
1347     CameraParameters adapterParams = mParameters;
1348     Mutex::Autolock lock(mLock);
1349 
1350     LOG_FUNCTION_NAME;
1351 
1352     if ( mBracketingRunning ) {
1353         stopImageBracketing();
1354     } else {
1355         mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
1356     }
1357 
1358     LOG_FUNCTION_NAME_EXIT;
1359 
1360     return ret;
1361 }
1362 
freeImageBufs()1363 status_t CameraHal::freeImageBufs()
1364 {
1365     status_t ret = NO_ERROR;
1366 
1367     LOG_FUNCTION_NAME;
1368 
1369     if ( NO_ERROR == ret )
1370         {
1371 
1372         if( NULL != mImageBufs )
1373             {
1374 
1375             ///@todo Pluralise the name of this method to freeBuffers
1376             ret = mMemoryManager->freeBuffer(mImageBufs);
1377             mImageBufs = NULL;
1378 
1379             }
1380         else
1381             {
1382             ret = -EINVAL;
1383             }
1384 
1385         }
1386 
1387     LOG_FUNCTION_NAME_EXIT;
1388 
1389     return ret;
1390 }
1391 
freeVideoBufs(void * bufs)1392 status_t CameraHal::freeVideoBufs(void *bufs)
1393 {
1394   status_t ret = NO_ERROR;
1395 
1396   LOG_FUNCTION_NAME;
1397 
1398   buffer_handle_t *pBuf = (buffer_handle_t*)bufs;
1399   int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
1400   if(pBuf == NULL)
1401     {
1402       CAMHAL_LOGEA("NULL pointer passed to freeVideoBuffer");
1403       LOG_FUNCTION_NAME_EXIT;
1404       return BAD_VALUE;
1405     }
1406 
1407   GraphicBufferAllocator &GrallocAlloc = GraphicBufferAllocator::get();
1408 
1409   for(int i = 0; i < count; i++){
1410     buffer_handle_t ptr = *pBuf++;
1411     CAMHAL_LOGVB("Free Video Gralloc Handle 0x%x", ptr);
1412     GrallocAlloc.free(ptr);
1413   }
1414 
1415   LOG_FUNCTION_NAME_EXIT;
1416 
1417   return ret;
1418 }
1419 
1420 /**
1421    @brief Start preview mode.
1422 
1423    @param none
1424    @return NO_ERROR Camera switched to VF mode
1425    @todo Update function header with the different errors that are possible
1426 
1427  */
startPreview()1428 status_t CameraHal::startPreview()
1429 {
1430 
1431     status_t ret = NO_ERROR;
1432     CameraAdapter::BuffersDescriptor desc;
1433     CameraFrame frame;
1434     const char *valstr = NULL;
1435     unsigned int required_buffer_count;
1436     unsigned int max_queueble_buffers;
1437 
1438 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1439         gettimeofday(&mStartPreview, NULL);
1440 #endif
1441 
1442     LOG_FUNCTION_NAME;
1443 
1444     if ( mPreviewEnabled ){
1445       CAMHAL_LOGDA("Preview already running");
1446       LOG_FUNCTION_NAME_EXIT;
1447       return ALREADY_EXISTS;
1448     }
1449 
1450     if ( NULL != mCameraAdapter ) {
1451       ret = mCameraAdapter->setParameters(mParameters);
1452     }
1453 
1454     if ((mPreviewStartInProgress == false) && (mDisplayPaused == false)){
1455       ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,( int ) &frame);
1456       if ( NO_ERROR != ret ){
1457         CAMHAL_LOGEB("Error: CAMERA_QUERY_RESOLUTION_PREVIEW %d", ret);
1458         return ret;
1459       }
1460 
1461       ///Update the current preview width and height
1462       mPreviewWidth = frame.mWidth;
1463       mPreviewHeight = frame.mHeight;
1464       //Update the padded width and height - required for VNF and VSTAB
1465       mParameters.set(TICameraParameters::KEY_PADDED_WIDTH, mPreviewWidth);
1466       mParameters.set(TICameraParameters::KEY_PADDED_HEIGHT, mPreviewHeight);
1467 
1468     }
1469 
1470     ///If we don't have the preview callback enabled and display adapter,
1471     if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL)){
1472       CAMHAL_LOGDA("Preview not started. Preview in progress flag set");
1473       mPreviewStartInProgress = true;
1474       ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SWITCH_TO_EXECUTING);
1475       if ( NO_ERROR != ret ){
1476         CAMHAL_LOGEB("Error: CAMERA_SWITCH_TO_EXECUTING %d", ret);
1477         return ret;
1478       }
1479       return NO_ERROR;
1480     }
1481 
1482     if( (mDisplayAdapter.get() != NULL) && ( !mPreviewEnabled ) && ( mDisplayPaused ) )
1483         {
1484         CAMHAL_LOGDA("Preview is in paused state");
1485 
1486         mDisplayPaused = false;
1487         mPreviewEnabled = true;
1488         if ( NO_ERROR == ret )
1489             {
1490             ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
1491 
1492             if ( NO_ERROR != ret )
1493                 {
1494                 CAMHAL_LOGEB("Display adapter resume failed %x", ret);
1495                 }
1496             }
1497         //restart preview callbacks
1498         if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
1499         {
1500             mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);
1501         }
1502         return ret;
1503         }
1504 
1505 
1506     required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
1507 
1508     ///Allocate the preview buffers
1509     ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers);
1510 
1511     if ( NO_ERROR != ret )
1512         {
1513         CAMHAL_LOGEA("Couldn't allocate buffers for Preview");
1514         goto error;
1515         }
1516 
1517     if ( mMeasurementEnabled )
1518         {
1519 
1520         ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA,
1521                                           ( int ) &frame,
1522                                           required_buffer_count);
1523         if ( NO_ERROR != ret )
1524             {
1525             return ret;
1526             }
1527 
1528          ///Allocate the preview data buffers
1529         ret = allocPreviewDataBufs(frame.mLength, required_buffer_count);
1530         if ( NO_ERROR != ret ) {
1531             CAMHAL_LOGEA("Couldn't allocate preview data buffers");
1532             goto error;
1533            }
1534 
1535         if ( NO_ERROR == ret )
1536             {
1537             desc.mBuffers = mPreviewDataBufs;
1538             desc.mOffsets = mPreviewDataOffsets;
1539             desc.mFd = mPreviewDataFd;
1540             desc.mLength = mPreviewDataLength;
1541             desc.mCount = ( size_t ) required_buffer_count;
1542             desc.mMaxQueueable = (size_t) required_buffer_count;
1543 
1544             mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW_DATA,
1545                                         ( int ) &desc);
1546             }
1547 
1548         }
1549 
1550     ///Pass the buffers to Camera Adapter
1551     desc.mBuffers = mPreviewBufs;
1552     desc.mOffsets = mPreviewOffsets;
1553     desc.mFd = mPreviewFd;
1554     desc.mLength = mPreviewLength;
1555     desc.mCount = ( size_t ) required_buffer_count;
1556     desc.mMaxQueueable = (size_t) max_queueble_buffers;
1557 
1558     ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW,
1559                                       ( int ) &desc);
1560 
1561     if ( NO_ERROR != ret )
1562         {
1563         CAMHAL_LOGEB("Failed to register preview buffers: 0x%x", ret);
1564         freePreviewBufs();
1565         return ret;
1566         }
1567 
1568     mAppCallbackNotifier->startPreviewCallbacks(mParameters, mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, required_buffer_count);
1569 
1570     ///Start the callback notifier
1571     ret = mAppCallbackNotifier->start();
1572 
1573     if( ALREADY_EXISTS == ret )
1574         {
1575         //Already running, do nothing
1576         CAMHAL_LOGDA("AppCallbackNotifier already running");
1577         ret = NO_ERROR;
1578         }
1579     else if ( NO_ERROR == ret ) {
1580         CAMHAL_LOGDA("Started AppCallbackNotifier..");
1581         mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
1582         }
1583     else
1584         {
1585         CAMHAL_LOGDA("Couldn't start AppCallbackNotifier");
1586         goto error;
1587         }
1588 
1589     ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
1590     if(mDisplayAdapter.get() != NULL)
1591         {
1592         CAMHAL_LOGDA("Enabling display");
1593         bool isS3d = false;
1594         DisplayAdapter::S3DParameters s3dParams;
1595         int width, height;
1596         mParameters.getPreviewSize(&width, &height);
1597 #if 0 //TODO: s3d is not part of bringup...will reenable
1598         if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_SUPPORTED)) != NULL) {
1599             isS3d = (strcmp(valstr, "true") == 0);
1600         }
1601         if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D2D_PREVIEW)) != NULL) {
1602             if (strcmp(valstr, "off") == 0)
1603                 {
1604                 CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS OFF");
1605                 //TODO: obtain the frame packing configuration from camera or user settings
1606                 //once side by side configuration is supported
1607                 s3dParams.mode = OVERLAY_S3D_MODE_ON;
1608                 s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
1609                 s3dParams.order = OVERLAY_S3D_ORDER_LF;
1610                 s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
1611                 }
1612             else
1613                 {
1614                 CAMHAL_LOGEA("STEREO 3D->2D PREVIEW MODE IS ON");
1615                 s3dParams.mode = OVERLAY_S3D_MODE_OFF;
1616                 s3dParams.framePacking = OVERLAY_S3D_FORMAT_OVERUNDER;
1617                 s3dParams.order = OVERLAY_S3D_ORDER_LF;
1618                 s3dParams.subSampling = OVERLAY_S3D_SS_NONE;
1619                 }
1620         }
1621 #endif //if 0
1622 
1623 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1624 
1625         ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview, isS3d ? &s3dParams : NULL);
1626 
1627 #else
1628 
1629         ret = mDisplayAdapter->enableDisplay(width, height, NULL, isS3d ? &s3dParams : NULL);
1630 
1631 #endif
1632 
1633         if ( ret != NO_ERROR )
1634             {
1635             CAMHAL_LOGEA("Couldn't enable display");
1636             goto error;
1637             }
1638 
1639         }
1640 
1641     ///Send START_PREVIEW command to adapter
1642     CAMHAL_LOGDA("Starting CameraAdapter preview mode");
1643 
1644     ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW);
1645 
1646     if(ret!=NO_ERROR)
1647         {
1648         CAMHAL_LOGEA("Couldn't start preview w/ CameraAdapter");
1649         goto error;
1650         }
1651     CAMHAL_LOGDA("Started preview");
1652 
1653     mPreviewEnabled = true;
1654     mPreviewStartInProgress = false;
1655     return ret;
1656 
1657     error:
1658 
1659         CAMHAL_LOGEA("Performing cleanup after error");
1660 
1661         //Do all the cleanup
1662         freePreviewBufs();
1663         mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
1664         if(mDisplayAdapter.get() != NULL)
1665             {
1666             mDisplayAdapter->disableDisplay(false);
1667             }
1668         mAppCallbackNotifier->stop();
1669         mPreviewStartInProgress = false;
1670         mPreviewEnabled = false;
1671         LOG_FUNCTION_NAME_EXIT;
1672 
1673         return ret;
1674 }
1675 
1676 /**
1677    @brief Sets ANativeWindow object.
1678 
1679    Preview buffers provided to CameraHal via this object. DisplayAdapter will be interfacing with it
1680    to render buffers to display.
1681 
1682    @param[in] window The ANativeWindow object created by Surface flinger
1683    @return NO_ERROR If the ANativeWindow object passes validation criteria
1684    @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
1685 
1686  */
setPreviewWindow(struct preview_stream_ops * window)1687 status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window)
1688 {
1689     status_t ret = NO_ERROR;
1690     CameraAdapter::BuffersDescriptor desc;
1691 
1692     LOG_FUNCTION_NAME;
1693     mSetPreviewWindowCalled = true;
1694 
1695    ///If the Camera service passes a null window, we destroy existing window and free the DisplayAdapter
1696     if(!window)
1697     {
1698         if(mDisplayAdapter.get() != NULL)
1699         {
1700             ///NULL window passed, destroy the display adapter if present
1701             CAMHAL_LOGDA("NULL window passed, destroying display adapter");
1702             mDisplayAdapter.clear();
1703             ///@remarks If there was a window previously existing, we usually expect another valid window to be passed by the client
1704             ///@remarks so, we will wait until it passes a valid window to begin the preview again
1705             mSetPreviewWindowCalled = false;
1706         }
1707         CAMHAL_LOGDA("NULL ANativeWindow passed to setPreviewWindow");
1708         return NO_ERROR;
1709     }else if(mDisplayAdapter.get() == NULL)
1710     {
1711         // Need to create the display adapter since it has not been created
1712         // Create display adapter
1713         mDisplayAdapter = new ANativeWindowDisplayAdapter();
1714         ret = NO_ERROR;
1715         if(!mDisplayAdapter.get() || ((ret=mDisplayAdapter->initialize())!=NO_ERROR))
1716         {
1717             if(ret!=NO_ERROR)
1718             {
1719                 mDisplayAdapter.clear();
1720                 CAMHAL_LOGEA("DisplayAdapter initialize failed");
1721                 LOG_FUNCTION_NAME_EXIT;
1722                 return ret;
1723             }
1724             else
1725             {
1726                 CAMHAL_LOGEA("Couldn't create DisplayAdapter");
1727                 LOG_FUNCTION_NAME_EXIT;
1728                 return NO_MEMORY;
1729             }
1730         }
1731 
1732         // DisplayAdapter needs to know where to get the CameraFrames from inorder to display
1733         // Since CameraAdapter is the one that provides the frames, set it as the frame provider for DisplayAdapter
1734         mDisplayAdapter->setFrameProvider(mCameraAdapter);
1735 
1736         // Any dynamic errors that happen during the camera use case has to be propagated back to the application
1737         // via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
1738         // Set it as the error handler for the DisplayAdapter
1739         mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get());
1740 
1741         // Update the display adapter with the new window that is passed from CameraService
1742         ret  = mDisplayAdapter->setPreviewWindow(window);
1743         if(ret!=NO_ERROR)
1744             {
1745             CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
1746             }
1747 
1748         if(mPreviewStartInProgress)
1749         {
1750             CAMHAL_LOGDA("setPreviewWindow called when preview running");
1751             // Start the preview since the window is now available
1752             ret = startPreview();
1753         }
1754     } else {
1755         // Update the display adapter with the new window that is passed from CameraService
1756         ret = mDisplayAdapter->setPreviewWindow(window);
1757         if ( (NO_ERROR == ret) && previewEnabled() ) {
1758             restartPreview();
1759         } else if (ret == ALREADY_EXISTS) {
1760             // ALREADY_EXISTS should be treated as a noop in this case
1761             ret = NO_ERROR;
1762         }
1763     }
1764     LOG_FUNCTION_NAME_EXIT;
1765 
1766     return ret;
1767 
1768 }
1769 
1770 
1771 /**
1772    @brief Stop a previously started preview.
1773 
1774    @param none
1775    @return none
1776 
1777  */
stopPreview()1778 void CameraHal::stopPreview()
1779 {
1780     LOG_FUNCTION_NAME;
1781 
1782     if( (!previewEnabled() && !mDisplayPaused) || mRecordingEnabled)
1783         {
1784         LOG_FUNCTION_NAME_EXIT;
1785         return;
1786         }
1787 
1788     bool imageCaptureRunning = (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE) &&
1789                                     (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE);
1790     if(mDisplayPaused && !imageCaptureRunning)
1791         {
1792         // Display is paused, which essentially means there is no preview active.
1793         // Note: this is done so that when stopPreview is called by client after
1794         // an image capture, we do not de-initialize the camera adapter and
1795         // restart over again.
1796 
1797         return;
1798         }
1799 
1800     forceStopPreview();
1801 
1802     // Reset Capture-Mode to default, so that when we switch from VideoRecording
1803     // to ImageCapture, CAPTURE_MODE is not left to VIDEO_MODE.
1804     CAMHAL_LOGDA("Resetting Capture-Mode to default");
1805     mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
1806 
1807     LOG_FUNCTION_NAME_EXIT;
1808 }
1809 
1810 /**
1811    @brief Returns true if preview is enabled
1812 
1813    @param none
1814    @return true If preview is running currently
1815          false If preview has been stopped
1816 
1817  */
previewEnabled()1818 bool CameraHal::previewEnabled()
1819 {
1820     LOG_FUNCTION_NAME;
1821 
1822     return (mPreviewEnabled || mPreviewStartInProgress);
1823 }
1824 
1825 /**
1826    @brief Start record mode.
1827 
1828   When a record image is available a CAMERA_MSG_VIDEO_FRAME message is sent with
1829   the corresponding frame. Every record frame must be released by calling
1830   releaseRecordingFrame().
1831 
1832    @param none
1833    @return NO_ERROR If recording could be started without any issues
1834    @todo Update the header with possible error values in failure scenarios
1835 
1836  */
startRecording()1837 status_t CameraHal::startRecording( )
1838 {
1839     int w, h;
1840     const char *valstr = NULL;
1841     bool restartPreviewRequired = false;
1842     status_t ret = NO_ERROR;
1843 
1844     LOG_FUNCTION_NAME;
1845 
1846 
1847 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1848 
1849             gettimeofday(&mStartPreview, NULL);
1850 
1851 #endif
1852 
1853     if(!previewEnabled())
1854         {
1855         return NO_INIT;
1856         }
1857 
1858     // set internal recording hint in case camera adapter needs to make some
1859     // decisions....(will only be sent to camera adapter if camera restart is required)
1860     mParameters.set(TICameraParameters::KEY_RECORDING_HINT, CameraParameters::TRUE);
1861 
1862     // if application starts recording in continuous focus picture mode...
1863     // then we need to force default capture mode (as opposed to video mode)
1864     if ( ((valstr = mParameters.get(CameraParameters::KEY_FOCUS_MODE)) != NULL) &&
1865          (strcmp(valstr, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0) ){
1866         restartPreviewRequired = resetVideoModeParameters();
1867     }
1868 
1869     // only need to check recording hint if preview restart is not already needed
1870     valstr = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
1871     if ( !restartPreviewRequired &&
1872          (!valstr || (valstr && (strcmp(valstr, CameraParameters::TRUE) != 0))) ) {
1873         restartPreviewRequired = setVideoModeParameters(mParameters);
1874     }
1875 
1876     if (restartPreviewRequired) {
1877         ret = restartPreview();
1878     }
1879 
1880     if ( NO_ERROR == ret )
1881       {
1882         int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
1883         mParameters.getPreviewSize(&w, &h);
1884         CAMHAL_LOGDB("%s Video Width=%d Height=%d", __FUNCTION__, mVideoWidth, mVideoHeight);
1885 
1886         if ((w != mVideoWidth) && (h != mVideoHeight))
1887           {
1888             ret = allocVideoBufs(mVideoWidth, mVideoHeight, count);
1889             if ( NO_ERROR != ret )
1890               {
1891                 CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
1892                 mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
1893                 return ret;
1894               }
1895 
1896             mAppCallbackNotifier->useVideoBuffers(true);
1897             mAppCallbackNotifier->setVideoRes(mVideoWidth, mVideoHeight);
1898             ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, count, mVideoBufs);
1899           }
1900         else
1901           {
1902             mAppCallbackNotifier->useVideoBuffers(false);
1903             mAppCallbackNotifier->setVideoRes(mPreviewWidth, mPreviewHeight);
1904             ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBufs, mPreviewOffsets, mPreviewFd, mPreviewLength, count, NULL);
1905           }
1906       }
1907 
1908     if ( NO_ERROR == ret )
1909         {
1910          ret = mAppCallbackNotifier->startRecording();
1911         }
1912 
1913     if ( NO_ERROR == ret )
1914         {
1915         ///Buffers for video capture (if different from preview) are expected to be allocated within CameraAdapter
1916          ret =  mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_VIDEO);
1917         }
1918 
1919     if ( NO_ERROR == ret )
1920         {
1921         mRecordingEnabled = true;
1922         }
1923 
1924     LOG_FUNCTION_NAME_EXIT;
1925 
1926     return ret;
1927 }
1928 
1929 /**
1930    @brief Set the camera parameters specific to Video Recording.
1931 
1932    This function checks for the camera parameters which have to be set for recording.
1933    Video Recording needs CAPTURE_MODE to be VIDEO_MODE. This function sets it.
1934    This function also enables Video Recording specific functions like VSTAB & VNF.
1935 
1936    @param none
1937    @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
1938    @todo Modify the policies for enabling VSTAB & VNF usecase based later.
1939 
1940  */
setVideoModeParameters(const CameraParameters & params)1941 bool CameraHal::setVideoModeParameters(const CameraParameters& params)
1942 {
1943     const char *valstr = NULL;
1944     const char *valstrRemote = NULL;
1945     bool restartPreviewRequired = false;
1946     status_t ret = NO_ERROR;
1947 
1948     LOG_FUNCTION_NAME;
1949 
1950     // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
1951     valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
1952     if ( (valstr == NULL) ||
1953         ( (valstr != NULL) && (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) != 0) ) )
1954         {
1955         CAMHAL_LOGDA("Set CAPTURE_MODE to VIDEO_MODE");
1956         mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_MODE);
1957         restartPreviewRequired = true;
1958         }
1959 
1960     // Check if CAPTURE_MODE is VIDEO_MODE, since VSTAB & VNF work only in VIDEO_MODE.
1961     valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
1962     if (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) == 0) {
1963        valstrRemote = params.get(CameraParameters::KEY_VIDEO_STABILIZATION);
1964        // set VSTAB. restart is required if vstab value has changed
1965        if ( valstrRemote != NULL) {
1966             // make sure we support vstab
1967             if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
1968                        CameraParameters::TRUE) == 0) {
1969                 valstr = mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION);
1970                 // vstab value has changed
1971                 if ((valstr != NULL) &&
1972                      strcmp(valstr, valstrRemote) != 0) {
1973                     restartPreviewRequired = true;
1974                 }
1975                 mParameters.set(CameraParameters::KEY_VIDEO_STABILIZATION, valstrRemote);
1976             }
1977         } else if (mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION)) {
1978             // vstab was configured but now unset
1979             restartPreviewRequired = true;
1980             mParameters.remove(CameraParameters::KEY_VIDEO_STABILIZATION);
1981         }
1982 
1983         // Set VNF
1984         valstrRemote = params.get(TICameraParameters::KEY_VNF);
1985         if ( valstrRemote == NULL) {
1986             CAMHAL_LOGDA("Enable VNF");
1987             mParameters.set(TICameraParameters::KEY_VNF, "1");
1988             restartPreviewRequired = true;
1989         } else {
1990             valstr = mParameters.get(TICameraParameters::KEY_VNF);
1991             if (valstr && strcmp(valstr, valstrRemote) != 0) {
1992                 restartPreviewRequired = true;
1993             }
1994             mParameters.set(TICameraParameters::KEY_VNF, valstrRemote);
1995         }
1996 
1997         // For VSTAB alone for 1080p resolution, padded width goes > 2048, which cannot be rendered by GPU.
1998         // In such case, there is support in Ducati for combination of VSTAB & VNF requiring padded width < 2048.
1999         // So we are forcefully enabling VNF, if VSTAB is enabled for 1080p resolution.
2000         valstr = mParameters.get(CameraParameters::KEY_VIDEO_STABILIZATION);
2001         if (valstr && (strcmp(valstr, CameraParameters::TRUE) == 0) && (mPreviewWidth == 1920)) {
2002             CAMHAL_LOGDA("Force Enable VNF for 1080p");
2003             mParameters.set(TICameraParameters::KEY_VNF, "1");
2004             restartPreviewRequired = true;
2005         }
2006     }
2007     LOG_FUNCTION_NAME_EXIT;
2008 
2009     return restartPreviewRequired;
2010 }
2011 
2012 /**
2013    @brief Reset the camera parameters specific to Video Recording.
2014 
2015    This function resets CAPTURE_MODE and disables Recording specific functions like VSTAB & VNF.
2016 
2017    @param none
2018    @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
2019 
2020  */
resetVideoModeParameters()2021 bool CameraHal::resetVideoModeParameters()
2022 {
2023     const char *valstr = NULL;
2024     bool restartPreviewRequired = false;
2025     status_t ret = NO_ERROR;
2026 
2027     LOG_FUNCTION_NAME;
2028 
2029     // ignore this if we are already recording
2030     if (mRecordingEnabled) {
2031         return false;
2032     }
2033 
2034     // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
2035     valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2036     if ((valstr != NULL) && (strcmp(valstr, TICameraParameters::VIDEO_MODE) == 0)) {
2037         CAMHAL_LOGDA("Reset Capture-Mode to default");
2038         mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
2039         restartPreviewRequired = true;
2040     }
2041 
2042     LOG_FUNCTION_NAME_EXIT;
2043 
2044     return restartPreviewRequired;
2045 }
2046 
2047 /**
2048    @brief Restart the preview with setParameter.
2049 
2050    This function restarts preview, for some VIDEO_MODE parameters to take effect.
2051 
2052    @param none
2053    @return NO_ERROR If recording parameters could be set without any issues
2054 
2055  */
restartPreview()2056 status_t CameraHal::restartPreview()
2057 {
2058     const char *valstr = NULL;
2059     char tmpvalstr[30];
2060     status_t ret = NO_ERROR;
2061 
2062     LOG_FUNCTION_NAME;
2063 
2064     // Retain CAPTURE_MODE before calling stopPreview(), since it is reset in stopPreview().
2065     tmpvalstr[0] = 0;
2066     valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2067     if(valstr != NULL)
2068         {
2069         if(sizeof(tmpvalstr) < (strlen(valstr)+1))
2070             {
2071             return -EINVAL;
2072             }
2073 
2074         strncpy(tmpvalstr, valstr, sizeof(tmpvalstr));
2075         tmpvalstr[sizeof(tmpvalstr)-1] = 0;
2076         }
2077 
2078     forceStopPreview();
2079 
2080     {
2081         Mutex::Autolock lock(mLock);
2082         mParameters.set(TICameraParameters::KEY_CAP_MODE, tmpvalstr);
2083         mCameraAdapter->setParameters(mParameters);
2084     }
2085 
2086     ret = startPreview();
2087 
2088     LOG_FUNCTION_NAME_EXIT;
2089 
2090     return ret;
2091 }
2092 
2093 /**
2094    @brief Stop a previously started recording.
2095 
2096    @param none
2097    @return none
2098 
2099  */
stopRecording()2100 void CameraHal::stopRecording()
2101 {
2102     CameraAdapter::AdapterState currentState;
2103 
2104     LOG_FUNCTION_NAME;
2105 
2106     Mutex::Autolock lock(mLock);
2107 
2108     if (!mRecordingEnabled )
2109         {
2110         return;
2111         }
2112 
2113     currentState = mCameraAdapter->getState();
2114     if (currentState == CameraAdapter::VIDEO_CAPTURE_STATE) {
2115         mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
2116     }
2117 
2118     mAppCallbackNotifier->stopRecording();
2119 
2120     mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_VIDEO);
2121 
2122     mRecordingEnabled = false;
2123 
2124     if ( mAppCallbackNotifier->getUesVideoBuffers() ){
2125       freeVideoBufs(mVideoBufs);
2126       if (mVideoBufs){
2127         CAMHAL_LOGVB(" FREEING mVideoBufs 0x%x", mVideoBufs);
2128         delete [] mVideoBufs;
2129       }
2130       mVideoBufs = NULL;
2131     }
2132 
2133     // reset internal recording hint in case camera adapter needs to make some
2134     // decisions....(will only be sent to camera adapter if camera restart is required)
2135     mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
2136 
2137     LOG_FUNCTION_NAME_EXIT;
2138 }
2139 
2140 /**
2141    @brief Returns true if recording is enabled.
2142 
2143    @param none
2144    @return true If recording is currently running
2145          false If recording has been stopped
2146 
2147  */
recordingEnabled()2148 int CameraHal::recordingEnabled()
2149 {
2150     LOG_FUNCTION_NAME;
2151 
2152     LOG_FUNCTION_NAME_EXIT;
2153 
2154     return mRecordingEnabled;
2155 }
2156 
2157 /**
2158    @brief Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
2159 
2160    @param[in] mem MemoryBase pointer to the frame being released. Must be one of the buffers
2161                previously given by CameraHal
2162    @return none
2163 
2164  */
releaseRecordingFrame(const void * mem)2165 void CameraHal::releaseRecordingFrame(const void* mem)
2166 {
2167     LOG_FUNCTION_NAME;
2168 
2169     //CAMHAL_LOGDB(" 0x%x", mem->pointer());
2170 
2171     if ( ( mRecordingEnabled ) && mem != NULL)
2172     {
2173         mAppCallbackNotifier->releaseRecordingFrame(mem);
2174     }
2175 
2176     LOG_FUNCTION_NAME_EXIT;
2177 
2178     return;
2179 }
2180 
2181 /**
2182    @brief Start auto focus
2183 
2184    This call asynchronous.
2185    The notification callback routine is called with CAMERA_MSG_FOCUS once when
2186    focusing is complete. autoFocus() will be called again if another auto focus is
2187    needed.
2188 
2189    @param none
2190    @return NO_ERROR
2191    @todo Define the error codes if the focus is not locked
2192 
2193  */
autoFocus()2194 status_t CameraHal::autoFocus()
2195 {
2196     status_t ret = NO_ERROR;
2197 
2198 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2199 
2200     gettimeofday(&mStartFocus, NULL);
2201 
2202 #endif
2203 
2204     LOG_FUNCTION_NAME;
2205 
2206     Mutex::Autolock lock(mLock);
2207 
2208     mMsgEnabled |= CAMERA_MSG_FOCUS;
2209 
2210     if ( NULL == mCameraAdapter )
2211         {
2212             ret = -1;
2213             goto EXIT;
2214         }
2215 
2216     CameraAdapter::AdapterState state;
2217     ret = mCameraAdapter->getState(state);
2218     if (ret != NO_ERROR)
2219         {
2220             goto EXIT;
2221         }
2222 
2223     if (state == CameraAdapter::AF_STATE)
2224         {
2225             CAMHAL_LOGI("Ignoring start-AF (already in progress)");
2226             goto EXIT;
2227         }
2228 
2229 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2230 
2231     //pass the autoFocus timestamp along with the command to camera adapter
2232     ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS, ( int ) &mStartFocus);
2233 
2234 #else
2235 
2236     ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS);
2237 
2238 #endif
2239 
2240 EXIT:
2241     LOG_FUNCTION_NAME_EXIT;
2242 
2243     return ret;
2244 }
2245 
2246 /**
2247    @brief Cancels auto-focus function.
2248 
2249    If the auto-focus is still in progress, this function will cancel it.
2250    Whether the auto-focus is in progress or not, this function will return the
2251    focus position to the default. If the camera does not support auto-focus, this is a no-op.
2252 
2253 
2254    @param none
2255    @return NO_ERROR If the cancel succeeded
2256    @todo Define error codes if cancel didnt succeed
2257 
2258  */
cancelAutoFocus()2259 status_t CameraHal::cancelAutoFocus()
2260 {
2261     LOG_FUNCTION_NAME;
2262 
2263     Mutex::Autolock lock(mLock);
2264     CameraParameters adapterParams = mParameters;
2265     mMsgEnabled &= ~CAMERA_MSG_FOCUS;
2266 
2267     if( NULL != mCameraAdapter )
2268     {
2269         adapterParams.set(TICameraParameters::KEY_AUTO_FOCUS_LOCK, CameraParameters::FALSE);
2270         mCameraAdapter->setParameters(adapterParams);
2271         mCameraAdapter->sendCommand(CameraAdapter::CAMERA_CANCEL_AUTOFOCUS);
2272         mAppCallbackNotifier->flushEventQueue();
2273     }
2274 
2275     LOG_FUNCTION_NAME_EXIT;
2276     return NO_ERROR;
2277 }
2278 
setEventProvider(int32_t eventMask,MessageNotifier * eventNotifier)2279 void CameraHal::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
2280 {
2281 
2282     LOG_FUNCTION_NAME;
2283 
2284     if ( NULL != mEventProvider )
2285         {
2286         mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
2287         delete mEventProvider;
2288         mEventProvider = NULL;
2289         }
2290 
2291     mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
2292     if ( NULL == mEventProvider )
2293         {
2294         CAMHAL_LOGEA("Error in creating EventProvider");
2295         }
2296     else
2297         {
2298         mEventProvider->enableEventNotification(eventMask);
2299         }
2300 
2301     LOG_FUNCTION_NAME_EXIT;
2302 }
2303 
eventCallbackRelay(CameraHalEvent * event)2304 void CameraHal::eventCallbackRelay(CameraHalEvent* event)
2305 {
2306     LOG_FUNCTION_NAME;
2307 
2308     CameraHal *appcbn = ( CameraHal * ) (event->mCookie);
2309     appcbn->eventCallback(event );
2310 
2311     LOG_FUNCTION_NAME_EXIT;
2312 }
2313 
eventCallback(CameraHalEvent * event)2314 void CameraHal::eventCallback(CameraHalEvent* event)
2315 {
2316     LOG_FUNCTION_NAME;
2317 
2318     if ( NULL != event )
2319         {
2320         switch( event->mEventType )
2321             {
2322             case CameraHalEvent::EVENT_FOCUS_LOCKED:
2323             case CameraHalEvent::EVENT_FOCUS_ERROR:
2324                 {
2325                 if ( mBracketingEnabled )
2326                     {
2327                     startImageBracketing();
2328                     }
2329                 break;
2330                 }
2331             default:
2332                 {
2333                 break;
2334                 }
2335             };
2336         }
2337 
2338     LOG_FUNCTION_NAME_EXIT;
2339 }
2340 
startImageBracketing()2341 status_t CameraHal::startImageBracketing()
2342 {
2343         status_t ret = NO_ERROR;
2344         CameraFrame frame;
2345         CameraAdapter::BuffersDescriptor desc;
2346 
2347 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2348 
2349         gettimeofday(&mStartCapture, NULL);
2350 
2351 #endif
2352 
2353         LOG_FUNCTION_NAME;
2354 
2355         if(!previewEnabled() && !mDisplayPaused)
2356             {
2357             LOG_FUNCTION_NAME_EXIT;
2358             return NO_INIT;
2359             }
2360 
2361         if ( !mBracketingEnabled )
2362             {
2363             return ret;
2364             }
2365 
2366         if ( NO_ERROR == ret )
2367             {
2368             mBracketingRunning = true;
2369             }
2370 
2371         if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
2372             {
2373             ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
2374                                               ( int ) &frame,
2375                                               ( mBracketRangeNegative + 1 ));
2376 
2377             if ( NO_ERROR != ret )
2378                 {
2379                 CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
2380                 }
2381             }
2382 
2383         if ( NO_ERROR == ret )
2384             {
2385             if ( NULL != mAppCallbackNotifier.get() )
2386                  {
2387                  mAppCallbackNotifier->setBurst(true);
2388                  }
2389             }
2390 
2391         if ( NO_ERROR == ret )
2392             {
2393             mParameters.getPictureSize(( int * ) &frame.mWidth,
2394                                        ( int * ) &frame.mHeight);
2395 
2396             ret = allocImageBufs(frame.mWidth,
2397                                  frame.mHeight,
2398                                  frame.mLength,
2399                                  mParameters.getPictureFormat(),
2400                                  ( mBracketRangeNegative + 1 ));
2401             if ( NO_ERROR != ret )
2402               {
2403                 CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
2404               }
2405             }
2406 
2407         if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
2408             {
2409 
2410             desc.mBuffers = mImageBufs;
2411             desc.mOffsets = mImageOffsets;
2412             desc.mFd = mImageFd;
2413             desc.mLength = mImageLength;
2414             desc.mCount = ( size_t ) ( mBracketRangeNegative + 1 );
2415             desc.mMaxQueueable = ( size_t ) ( mBracketRangeNegative + 1 );
2416 
2417             ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
2418                                               ( int ) &desc);
2419 
2420             if ( NO_ERROR == ret )
2421                 {
2422 
2423 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2424 
2425                  //pass capture timestamp along with the camera adapter command
2426                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE,  ( mBracketRangePositive + 1 ),  (int) &mStartCapture);
2427 
2428 #else
2429 
2430                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE, ( mBracketRangePositive + 1 ));
2431 
2432 #endif
2433 
2434                 }
2435             }
2436 
2437         return ret;
2438 }
2439 
stopImageBracketing()2440 status_t CameraHal::stopImageBracketing()
2441 {
2442         status_t ret = NO_ERROR;
2443 
2444         LOG_FUNCTION_NAME;
2445 
2446         if( !previewEnabled() )
2447             {
2448             return NO_INIT;
2449             }
2450 
2451         mBracketingRunning = false;
2452 
2453         ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_BRACKET_CAPTURE);
2454 
2455         LOG_FUNCTION_NAME_EXIT;
2456 
2457         return ret;
2458 }
2459 
2460 /**
2461    @brief Take a picture.
2462 
2463    @param none
2464    @return NO_ERROR If able to switch to image capture
2465    @todo Define error codes if unable to switch to image capture
2466 
2467  */
takePicture()2468 status_t CameraHal::takePicture( )
2469 {
2470     status_t ret = NO_ERROR;
2471     CameraFrame frame;
2472     CameraAdapter::BuffersDescriptor desc;
2473     int burst;
2474     const char *valstr = NULL;
2475     unsigned int bufferCount = 1;
2476 
2477     Mutex::Autolock lock(mLock);
2478 
2479 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2480 
2481     gettimeofday(&mStartCapture, NULL);
2482 
2483 #endif
2484 
2485     LOG_FUNCTION_NAME;
2486 
2487     if(!previewEnabled() && !mDisplayPaused)
2488         {
2489         LOG_FUNCTION_NAME_EXIT;
2490         CAMHAL_LOGEA("Preview not started...");
2491         return NO_INIT;
2492         }
2493 
2494     // return error if we are already capturing
2495     if ( (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
2496           mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) ||
2497          (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE &&
2498           mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE) ) {
2499         CAMHAL_LOGEA("Already capturing an image...");
2500         return NO_INIT;
2501     }
2502 
2503     // we only support video snapshot if we are in video mode (recording hint is set)
2504     valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2505     if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) &&
2506          (valstr && strcmp(valstr, TICameraParameters::VIDEO_MODE)) ) {
2507         CAMHAL_LOGEA("Trying to capture while recording without recording hint set...");
2508         return INVALID_OPERATION;
2509     }
2510 
2511     if ( !mBracketingRunning )
2512         {
2513 
2514          if ( NO_ERROR == ret )
2515             {
2516             burst = mParameters.getInt(TICameraParameters::KEY_BURST);
2517             }
2518 
2519          //Allocate all buffers only in burst capture case
2520          if ( burst > 1 )
2521              {
2522              bufferCount = CameraHal::NO_BUFFERS_IMAGE_CAPTURE;
2523              if ( NULL != mAppCallbackNotifier.get() )
2524                  {
2525                  mAppCallbackNotifier->setBurst(true);
2526                  }
2527              }
2528          else
2529              {
2530              if ( NULL != mAppCallbackNotifier.get() )
2531                  {
2532                  mAppCallbackNotifier->setBurst(false);
2533                  }
2534              }
2535 
2536         // pause preview during normal image capture
2537         // do not pause preview if recording (video state)
2538         if (NO_ERROR == ret &&
2539                 NULL != mDisplayAdapter.get() &&
2540                 burst < 1) {
2541             if (mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) {
2542                 mDisplayPaused = true;
2543                 mPreviewEnabled = false;
2544                 ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
2545                 // since preview is paused we should stop sending preview frames too
2546                 if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
2547                     mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
2548                 }
2549             }
2550 
2551 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2552             mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
2553 #endif
2554         }
2555 
2556         // if we taking video snapshot...
2557         if ((NO_ERROR == ret) && (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE)) {
2558             // enable post view frames if not already enabled so we can internally
2559             // save snapshot frames for generating thumbnail
2560             if((mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) == 0) {
2561                 mAppCallbackNotifier->enableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
2562             }
2563         }
2564 
2565         if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) )
2566             {
2567             if ( NO_ERROR == ret )
2568                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
2569                                                   ( int ) &frame,
2570                                                   bufferCount);
2571 
2572             if ( NO_ERROR != ret )
2573                 {
2574                 CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
2575                 }
2576             }
2577 
2578         if ( NO_ERROR == ret )
2579             {
2580             mParameters.getPictureSize(( int * ) &frame.mWidth,
2581                                        ( int * ) &frame.mHeight);
2582 
2583             ret = allocImageBufs(frame.mWidth,
2584                                  frame.mHeight,
2585                                  frame.mLength,
2586                                  mParameters.getPictureFormat(),
2587                                  bufferCount);
2588             if ( NO_ERROR != ret )
2589                 {
2590                 CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
2591                 }
2592             }
2593 
2594         if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
2595             {
2596             desc.mBuffers = mImageBufs;
2597             desc.mOffsets = mImageOffsets;
2598             desc.mFd = mImageFd;
2599             desc.mLength = mImageLength;
2600             desc.mCount = ( size_t ) bufferCount;
2601             desc.mMaxQueueable = ( size_t ) bufferCount;
2602 
2603             ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
2604                                               ( int ) &desc);
2605             }
2606         }
2607 
2608     if ( ( NO_ERROR == ret ) && ( NULL != mCameraAdapter ) )
2609         {
2610 
2611 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2612 
2613          //pass capture timestamp along with the camera adapter command
2614         ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE,  (int) &mStartCapture);
2615 
2616 #else
2617 
2618         ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);
2619 
2620 #endif
2621 
2622         }
2623 
2624     return ret;
2625 }
2626 
2627 /**
2628    @brief Cancel a picture that was started with takePicture.
2629 
2630    Calling this method when no picture is being taken is a no-op.
2631 
2632    @param none
2633    @return NO_ERROR If cancel succeeded. Cancel can succeed if image callback is not sent
2634    @todo Define error codes
2635 
2636  */
cancelPicture()2637 status_t CameraHal::cancelPicture( )
2638 {
2639     LOG_FUNCTION_NAME;
2640 
2641     Mutex::Autolock lock(mLock);
2642 
2643     mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
2644 
2645     return NO_ERROR;
2646 }
2647 
2648 /**
2649    @brief Return the camera parameters.
2650 
2651    @param none
2652    @return Currently configured camera parameters
2653 
2654  */
getParameters()2655 char* CameraHal::getParameters()
2656 {
2657     String8 params_str8;
2658     char* params_string;
2659     const char * valstr = NULL;
2660 
2661     LOG_FUNCTION_NAME;
2662 
2663     if( NULL != mCameraAdapter )
2664     {
2665         mCameraAdapter->getParameters(mParameters);
2666     }
2667 
2668     CameraParameters mParams = mParameters;
2669 
2670     // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
2671     valstr = mParameters.get(CameraParameters::KEY_RECORDING_HINT);
2672     if(valstr != NULL)
2673       {
2674         if(strcmp(valstr, CameraParameters::TRUE) == 0)
2675           {
2676             //HACK FOR MMS MODE
2677             resetPreviewRes(&mParams, mVideoWidth, mVideoHeight);
2678           }
2679       }
2680 
2681     // do not send internal parameters to upper layers
2682     mParams.remove(TICameraParameters::KEY_RECORDING_HINT);
2683     mParams.remove(TICameraParameters::KEY_AUTO_FOCUS_LOCK);
2684 
2685     params_str8 = mParams.flatten();
2686 
2687     // camera service frees this string...
2688     params_string = (char*) malloc(sizeof(char) * (params_str8.length()+1));
2689     strcpy(params_string, params_str8.string());
2690 
2691     LOG_FUNCTION_NAME_EXIT;
2692 
2693     ///Return the current set of parameters
2694 
2695     return params_string;
2696 }
2697 
putParameters(char * parms)2698 void CameraHal::putParameters(char *parms)
2699 {
2700     free(parms);
2701 }
2702 
2703 /**
2704    @brief Send command to camera driver.
2705 
2706    @param none
2707    @return NO_ERROR If the command succeeds
2708    @todo Define the error codes that this function can return
2709 
2710  */
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)2711 status_t CameraHal::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
2712 {
2713     status_t ret = NO_ERROR;
2714 
2715     LOG_FUNCTION_NAME;
2716 
2717 
2718     if ( ( NO_ERROR == ret ) && ( NULL == mCameraAdapter ) )
2719         {
2720         CAMHAL_LOGEA("No CameraAdapter instance");
2721         return -EINVAL;
2722         }
2723 
2724     ///////////////////////////////////////////////////////
2725     // Following commands do NOT need preview to be started
2726     ///////////////////////////////////////////////////////
2727     switch(cmd) {
2728         case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
2729             bool enable = static_cast<bool>(arg1);
2730             Mutex::Autolock lock(mLock);
2731             if (enable) {
2732                 mMsgEnabled |= CAMERA_MSG_FOCUS_MOVE;
2733             } else {
2734                 mMsgEnabled &= ~CAMERA_MSG_FOCUS_MOVE;
2735             }
2736             return NO_ERROR;
2737         break;
2738     }
2739 
2740     if ( ( NO_ERROR == ret ) && ( !previewEnabled() ))
2741         {
2742         CAMHAL_LOGEA("Preview is not running");
2743         ret = -EINVAL;
2744         }
2745 
2746     ///////////////////////////////////////////////////////
2747     // Following commands NEED preview to be started
2748     ///////////////////////////////////////////////////////
2749 
2750     if ( NO_ERROR == ret )
2751         {
2752         switch(cmd)
2753             {
2754             case CAMERA_CMD_START_SMOOTH_ZOOM:
2755 
2756                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_SMOOTH_ZOOM, arg1);
2757 
2758                 break;
2759             case CAMERA_CMD_STOP_SMOOTH_ZOOM:
2760 
2761                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);
2762 
2763             case CAMERA_CMD_START_FACE_DETECTION:
2764 
2765                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);
2766 
2767                 break;
2768 
2769             case CAMERA_CMD_STOP_FACE_DETECTION:
2770 
2771                 ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
2772 
2773                 break;
2774 
2775             default:
2776                 break;
2777             };
2778         }
2779 
2780     LOG_FUNCTION_NAME_EXIT;
2781 
2782     return ret;
2783 }
2784 
2785 /**
2786    @brief Release the hardware resources owned by this object.
2787 
2788    Note that this is *not* done in the destructor.
2789 
2790    @param none
2791    @return none
2792 
2793  */
release()2794 void CameraHal::release()
2795 {
2796     LOG_FUNCTION_NAME;
2797     ///@todo Investigate on how release is used by CameraService. Vaguely remember that this is called
2798     ///just before CameraHal object destruction
2799     deinitialize();
2800     LOG_FUNCTION_NAME_EXIT;
2801 }
2802 
2803 
2804 /**
2805    @brief Dump state of the camera hardware
2806 
2807    @param[in] fd    File descriptor
2808    @param[in] args  Arguments
2809    @return NO_ERROR Dump succeeded
2810    @todo  Error codes for dump fail
2811 
2812  */
dump(int fd) const2813 status_t  CameraHal::dump(int fd) const
2814 {
2815     LOG_FUNCTION_NAME;
2816     ///Implement this method when the h/w dump function is supported on Ducati side
2817     return NO_ERROR;
2818 }
2819 
2820 /*-------------Camera Hal Interface Method definitions ENDS here--------------------*/
2821 
2822 
2823 
2824 
2825 /*-------------Camera Hal Internal Method definitions STARTS here--------------------*/
2826 
2827 /**
2828    @brief Constructor of CameraHal
2829 
2830    Member variables are initialized here.  No allocations should be done here as we
2831    don't use c++ exceptions in the code.
2832 
2833  */
CameraHal(int cameraId)2834 CameraHal::CameraHal(int cameraId)
2835 {
2836     LOG_FUNCTION_NAME;
2837 
2838     ///Initialize all the member variables to their defaults
2839     mPreviewEnabled = false;
2840     mPreviewBufs = NULL;
2841     mImageBufs = NULL;
2842     mBufProvider = NULL;
2843     mPreviewStartInProgress = false;
2844     mVideoBufs = NULL;
2845     mVideoBufProvider = NULL;
2846     mRecordingEnabled = false;
2847     mDisplayPaused = false;
2848     mSetPreviewWindowCalled = false;
2849     mMsgEnabled = 0;
2850     mAppCallbackNotifier = NULL;
2851     mMemoryManager = NULL;
2852     mCameraAdapter = NULL;
2853     mBracketingEnabled = false;
2854     mBracketingRunning = false;
2855     mEventProvider = NULL;
2856     mBracketRangePositive = 1;
2857     mBracketRangeNegative = 1;
2858     mMaxZoomSupported = 0;
2859     mShutterEnabled = true;
2860     mMeasurementEnabled = false;
2861     mPreviewDataBufs = NULL;
2862     mCameraProperties = NULL;
2863     mCurrentTime = 0;
2864     mFalsePreview = 0;
2865     mImageOffsets = NULL;
2866     mImageLength = 0;
2867     mImageFd = 0;
2868     mVideoOffsets = NULL;
2869     mVideoFd = 0;
2870     mVideoLength = 0;
2871     mPreviewDataOffsets = NULL;
2872     mPreviewDataFd = 0;
2873     mPreviewDataLength = 0;
2874     mPreviewFd = 0;
2875     mPreviewWidth = 0;
2876     mPreviewHeight = 0;
2877     mPreviewLength = 0;
2878     mPreviewOffsets = NULL;
2879     mPreviewRunning = 0;
2880     mPreviewStateOld = 0;
2881     mRecordingEnabled = 0;
2882     mRecordEnabled = 0;
2883     mSensorListener = NULL;
2884     mVideoWidth = 0;
2885     mVideoHeight = 0;
2886 
2887 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2888 
2889     //Initialize the CameraHAL constructor timestamp, which is used in the
2890     // PPM() method as time reference if the user does not supply one.
2891     gettimeofday(&ppm_start, NULL);
2892 
2893 #endif
2894 
2895     mCameraIndex = cameraId;
2896 
2897     LOG_FUNCTION_NAME_EXIT;
2898 }
2899 
2900 /**
2901    @brief Destructor of CameraHal
2902 
2903    This function simply calls deinitialize() to free up memory allocate during construct
2904    phase
2905  */
~CameraHal()2906 CameraHal::~CameraHal()
2907 {
2908     LOG_FUNCTION_NAME;
2909 
2910     ///Call de-initialize here once more - it is the last chance for us to relinquish all the h/w and s/w resources
2911     deinitialize();
2912 
2913     if ( NULL != mEventProvider )
2914         {
2915         mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
2916         delete mEventProvider;
2917         mEventProvider = NULL;
2918         }
2919 
2920     /// Free the callback notifier
2921     mAppCallbackNotifier.clear();
2922 
2923     /// Free the display adapter
2924     mDisplayAdapter.clear();
2925 
2926     if ( NULL != mCameraAdapter ) {
2927         int strongCount = mCameraAdapter->getStrongCount();
2928 
2929         mCameraAdapter->decStrong(mCameraAdapter);
2930 
2931         mCameraAdapter = NULL;
2932     }
2933 
2934     freeImageBufs();
2935 
2936     /// Free the memory manager
2937     mMemoryManager.clear();
2938 
2939     LOG_FUNCTION_NAME_EXIT;
2940 }
2941 
2942 /**
2943    @brief Initialize the Camera HAL
2944 
2945    Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager
2946 
2947    @param None
2948    @return NO_ERROR - On success
2949          NO_MEMORY - On failure to allocate memory for any of the objects
2950    @remarks Camera Hal internal function
2951 
2952  */
2953 
initialize(CameraProperties::Properties * properties)2954 status_t CameraHal::initialize(CameraProperties::Properties* properties)
2955 {
2956     LOG_FUNCTION_NAME;
2957 
2958     int sensor_index = 0;
2959 
2960     ///Initialize the event mask used for registering an event provider for AppCallbackNotifier
2961     ///Currently, registering all events as to be coming from CameraAdapter
2962     int32_t eventMask = CameraHalEvent::ALL_EVENTS;
2963 
2964     // Get my camera properties
2965     mCameraProperties = properties;
2966 
2967     if(!mCameraProperties)
2968     {
2969         goto fail_loop;
2970     }
2971 
2972     // Dump the properties of this Camera
2973     // will only print if DEBUG macro is defined
2974     mCameraProperties->dump();
2975 
2976     if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 )
2977         {
2978         sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX));
2979         }
2980 
2981     CAMHAL_LOGDB("Sensor index %d", sensor_index);
2982 
2983     mCameraAdapter = CameraAdapter_Factory(sensor_index);
2984     if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR))
2985         {
2986         CAMHAL_LOGEA("Unable to create or initialize CameraAdapter");
2987         mCameraAdapter = NULL;
2988         goto fail_loop;
2989         }
2990 
2991     mCameraAdapter->incStrong(mCameraAdapter);
2992     mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
2993     mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);
2994 
2995     if(!mAppCallbackNotifier.get())
2996         {
2997         /// Create the callback notifier
2998         mAppCallbackNotifier = new AppCallbackNotifier();
2999         if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR))
3000             {
3001             CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier");
3002             goto fail_loop;
3003             }
3004         }
3005 
3006     if(!mMemoryManager.get())
3007         {
3008         /// Create Memory Manager
3009         mMemoryManager = new MemoryManager();
3010         if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR))
3011             {
3012             CAMHAL_LOGEA("Unable to create or initialize MemoryManager");
3013             goto fail_loop;
3014             }
3015         }
3016 
3017     ///Setup the class dependencies...
3018 
3019     ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from.
3020     ///CameraAdapter is the one which provides those events
3021     ///Set it as the frame and event providers for AppCallbackNotifier
3022     ///@remarks  setEventProvider API takes in a bit mask of events for registering a provider for the different events
3023     ///         That way, if events can come from DisplayAdapter in future, we will be able to add it as provider
3024     ///         for any event
3025     mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
3026     mAppCallbackNotifier->setFrameProvider(mCameraAdapter);
3027 
3028     ///Any dynamic errors that happen during the camera use case has to be propagated back to the application
3029     ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
3030     ///Set it as the error handler for CameraAdapter
3031     mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());
3032 
3033     ///Start the callback notifier
3034     if(mAppCallbackNotifier->start() != NO_ERROR)
3035       {
3036         CAMHAL_LOGEA("Couldn't start AppCallbackNotifier");
3037         goto fail_loop;
3038       }
3039 
3040     CAMHAL_LOGDA("Started AppCallbackNotifier..");
3041     mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
3042 
3043     ///Initialize default parameters
3044     initDefaultParameters();
3045 
3046 
3047     if ( setParameters(mParameters) != NO_ERROR )
3048         {
3049         CAMHAL_LOGEA("Failed to set default parameters?!");
3050         }
3051 
3052     // register for sensor events
3053     mSensorListener = new SensorListener();
3054     if (mSensorListener.get()) {
3055         if (mSensorListener->initialize() == NO_ERROR) {
3056             mSensorListener->setCallbacks(orientation_cb, this);
3057             mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
3058         } else {
3059             CAMHAL_LOGEA("Error initializing SensorListener. not fatal, continuing");
3060             mSensorListener.clear();
3061             mSensorListener = NULL;
3062         }
3063     }
3064 
3065     LOG_FUNCTION_NAME_EXIT;
3066 
3067     return NO_ERROR;
3068 
3069     fail_loop:
3070 
3071         ///Free up the resources because we failed somewhere up
3072         deinitialize();
3073         LOG_FUNCTION_NAME_EXIT;
3074 
3075         return NO_MEMORY;
3076 
3077 }
3078 
isResolutionValid(unsigned int width,unsigned int height,const char * supportedResolutions)3079 bool CameraHal::isResolutionValid(unsigned int width, unsigned int height, const char *supportedResolutions)
3080 {
3081     bool ret = true;
3082     status_t status = NO_ERROR;
3083     char tmpBuffer[PARAM_BUFFER + 1];
3084     char *pos = NULL;
3085 
3086     LOG_FUNCTION_NAME;
3087 
3088     if ( NULL == supportedResolutions )
3089         {
3090         CAMHAL_LOGEA("Invalid supported resolutions string");
3091         ret = false;
3092         goto exit;
3093         }
3094 
3095     status = snprintf(tmpBuffer, PARAM_BUFFER, "%dx%d", width, height);
3096     if ( 0 > status )
3097         {
3098         CAMHAL_LOGEA("Error encountered while generating validation string");
3099         ret = false;
3100         goto exit;
3101         }
3102 
3103     pos = strstr(supportedResolutions, tmpBuffer);
3104     if ( NULL == pos )
3105         {
3106         ret = false;
3107         }
3108     else
3109         {
3110         ret = true;
3111         }
3112 
3113 exit:
3114 
3115     LOG_FUNCTION_NAME_EXIT;
3116 
3117     return ret;
3118 }
3119 
isParameterValid(const char * param,const char * supportedParams)3120 bool CameraHal::isParameterValid(const char *param, const char *supportedParams)
3121 {
3122     bool ret = true;
3123     char *pos = NULL;
3124 
3125     LOG_FUNCTION_NAME;
3126 
3127     if ( NULL == supportedParams )
3128         {
3129         CAMHAL_LOGEA("Invalid supported parameters string");
3130         ret = false;
3131         goto exit;
3132         }
3133 
3134     if ( NULL == param )
3135         {
3136         CAMHAL_LOGEA("Invalid parameter string");
3137         ret = false;
3138         goto exit;
3139         }
3140 
3141     pos = strstr(supportedParams, param);
3142     if ( NULL == pos )
3143         {
3144         ret = false;
3145         }
3146     else
3147         {
3148         ret = true;
3149         }
3150 
3151 exit:
3152 
3153     LOG_FUNCTION_NAME_EXIT;
3154 
3155     return ret;
3156 }
3157 
isParameterValid(int param,const char * supportedParams)3158 bool CameraHal::isParameterValid(int param, const char *supportedParams)
3159 {
3160     bool ret = true;
3161     char *pos = NULL;
3162     status_t status;
3163     char tmpBuffer[PARAM_BUFFER + 1];
3164 
3165     LOG_FUNCTION_NAME;
3166 
3167     if ( NULL == supportedParams )
3168         {
3169         CAMHAL_LOGEA("Invalid supported parameters string");
3170         ret = false;
3171         goto exit;
3172         }
3173 
3174     status = snprintf(tmpBuffer, PARAM_BUFFER, "%d", param);
3175     if ( 0 > status )
3176         {
3177         CAMHAL_LOGEA("Error encountered while generating validation string");
3178         ret = false;
3179         goto exit;
3180         }
3181 
3182     pos = strstr(supportedParams, tmpBuffer);
3183     if ( NULL == pos )
3184         {
3185         ret = false;
3186         }
3187     else
3188         {
3189         ret = true;
3190         }
3191 
3192 exit:
3193 
3194     LOG_FUNCTION_NAME_EXIT;
3195 
3196     return ret;
3197 }
3198 
doesSetParameterNeedUpdate(const char * new_param,const char * old_param,bool & update)3199 status_t CameraHal::doesSetParameterNeedUpdate(const char* new_param, const char* old_param, bool& update) {
3200     if (!new_param || !old_param) {
3201         return -EINVAL;
3202     }
3203 
3204     // if params mismatch we should update parameters for camera adapter
3205     if ((strcmp(new_param, old_param) != 0)) {
3206        update = true;
3207     }
3208 
3209    return NO_ERROR;
3210 }
3211 
parseResolution(const char * resStr,int & width,int & height)3212 status_t CameraHal::parseResolution(const char *resStr, int &width, int &height)
3213 {
3214     status_t ret = NO_ERROR;
3215     char *ctx, *pWidth, *pHeight;
3216     const char *sep = "x";
3217     char *tmp = NULL;
3218 
3219     LOG_FUNCTION_NAME;
3220 
3221     if ( NULL == resStr )
3222         {
3223         return -EINVAL;
3224         }
3225 
3226     //This fixes "Invalid input resolution"
3227     char *resStr_copy = (char *)malloc(strlen(resStr) + 1);
3228     if ( NULL!=resStr_copy ) {
3229     if ( NO_ERROR == ret )
3230         {
3231         strcpy(resStr_copy, resStr);
3232         pWidth = strtok_r( (char *) resStr_copy, sep, &ctx);
3233 
3234         if ( NULL != pWidth )
3235             {
3236             width = atoi(pWidth);
3237             }
3238         else
3239             {
3240             CAMHAL_LOGEB("Invalid input resolution %s", resStr);
3241             ret = -EINVAL;
3242             }
3243         }
3244 
3245     if ( NO_ERROR == ret )
3246         {
3247         pHeight = strtok_r(NULL, sep, &ctx);
3248 
3249         if ( NULL != pHeight )
3250             {
3251             height = atoi(pHeight);
3252             }
3253         else
3254             {
3255             CAMHAL_LOGEB("Invalid input resolution %s", resStr);
3256             ret = -EINVAL;
3257             }
3258         }
3259 
3260         free(resStr_copy);
3261         resStr_copy = NULL;
3262      }
3263     LOG_FUNCTION_NAME_EXIT;
3264 
3265     return ret;
3266 }
3267 
insertSupportedParams()3268 void CameraHal::insertSupportedParams()
3269 {
3270     char tmpBuffer[PARAM_BUFFER + 1];
3271 
3272     LOG_FUNCTION_NAME;
3273 
3274     CameraParameters &p = mParameters;
3275 
3276     ///Set the name of the camera
3277     p.set(TICameraParameters::KEY_CAMERA_NAME, mCameraProperties->get(CameraProperties::CAMERA_NAME));
3278 
3279     mMaxZoomSupported = atoi(mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
3280 
3281     p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES));
3282     p.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS));
3283     p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES));
3284     p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
3285     p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
3286     p.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_THUMBNAIL_SIZES));
3287     p.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE));
3288     p.set(CameraParameters::KEY_SUPPORTED_EFFECTS, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS));
3289     p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
3290     p.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES));
3291     p.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES));
3292     p.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING));
3293     p.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MAX));
3294     p.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MIN));
3295     p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_EV_STEP));
3296     p.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
3297     p.set(TICameraParameters::KEY_SUPPORTED_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES));
3298     p.set(TICameraParameters::KEY_SUPPORTED_ISO_VALUES, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES));
3299     p.set(CameraParameters::KEY_ZOOM_RATIOS, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_RATIOS));
3300     p.set(CameraParameters::KEY_MAX_ZOOM, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
3301     p.set(CameraParameters::KEY_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::ZOOM_SUPPORTED));
3302     p.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::SMOOTH_ZOOM_SUPPORTED));
3303     p.set(TICameraParameters::KEY_SUPPORTED_IPP, mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES));
3304     p.set(TICameraParameters::KEY_S3D_SUPPORTED,mCameraProperties->get(CameraProperties::S3D_SUPPORTED));
3305     p.set(TICameraParameters::KEY_S3D2D_PREVIEW_MODE,mCameraProperties->get(CameraProperties::S3D2D_PREVIEW_MODES));
3306     p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE));
3307     p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
3308     p.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED));
3309     p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
3310     p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
3311     p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
3312     p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK_SUPPORTED));
3313     p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK_SUPPORTED));
3314     p.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, mCameraProperties->get(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED));
3315 
3316     LOG_FUNCTION_NAME_EXIT;
3317 
3318 }
3319 
initDefaultParameters()3320 void CameraHal::initDefaultParameters()
3321 {
3322     //Purpose of this function is to initialize the default current and supported parameters for the currently
3323     //selected camera.
3324 
3325     CameraParameters &p = mParameters;
3326     int currentRevision, adapterRevision;
3327     status_t ret = NO_ERROR;
3328     int width, height;
3329 
3330     LOG_FUNCTION_NAME;
3331 
3332     ret = parseResolution(mCameraProperties->get(CameraProperties::PREVIEW_SIZE), width, height);
3333 
3334     if ( NO_ERROR == ret )
3335         {
3336         p.setPreviewSize(width, height);
3337         }
3338     else
3339         {
3340         p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
3341         }
3342 
3343     ret = parseResolution(mCameraProperties->get(CameraProperties::PICTURE_SIZE), width, height);
3344 
3345     if ( NO_ERROR == ret )
3346         {
3347         p.setPictureSize(width, height);
3348         }
3349     else
3350         {
3351         p.setPictureSize(PICTURE_WIDTH, PICTURE_HEIGHT);
3352         }
3353 
3354     ret = parseResolution(mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_SIZE), width, height);
3355 
3356     if ( NO_ERROR == ret )
3357         {
3358         p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
3359         p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
3360         }
3361     else
3362         {
3363         p.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, MIN_WIDTH);
3364         p.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, MIN_HEIGHT);
3365         }
3366 
3367     insertSupportedParams();
3368 
3369     //Insert default values
3370     p.setPreviewFrameRate(atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)));
3371     p.setPreviewFormat(mCameraProperties->get(CameraProperties::PREVIEW_FORMAT));
3372     p.setPictureFormat(mCameraProperties->get(CameraProperties::PICTURE_FORMAT));
3373     p.set(CameraParameters::KEY_JPEG_QUALITY, mCameraProperties->get(CameraProperties::JPEG_QUALITY));
3374     p.set(CameraParameters::KEY_WHITE_BALANCE, mCameraProperties->get(CameraProperties::WHITEBALANCE));
3375     p.set(CameraParameters::KEY_EFFECT,  mCameraProperties->get(CameraProperties::EFFECT));
3376     p.set(CameraParameters::KEY_ANTIBANDING, mCameraProperties->get(CameraProperties::ANTIBANDING));
3377     p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
3378     p.set(CameraParameters::KEY_FOCUS_MODE, mCameraProperties->get(CameraProperties::FOCUS_MODE));
3379     p.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::EV_COMPENSATION));
3380     p.set(CameraParameters::KEY_SCENE_MODE, mCameraProperties->get(CameraProperties::SCENE_MODE));
3381     p.set(CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
3382     p.set(CameraParameters::KEY_ZOOM, mCameraProperties->get(CameraProperties::ZOOM));
3383     p.set(TICameraParameters::KEY_CONTRAST, mCameraProperties->get(CameraProperties::CONTRAST));
3384     p.set(TICameraParameters::KEY_SATURATION, mCameraProperties->get(CameraProperties::SATURATION));
3385     p.set(TICameraParameters::KEY_BRIGHTNESS, mCameraProperties->get(CameraProperties::BRIGHTNESS));
3386     p.set(TICameraParameters::KEY_SHARPNESS, mCameraProperties->get(CameraProperties::SHARPNESS));
3387     p.set(TICameraParameters::KEY_EXPOSURE_MODE, mCameraProperties->get(CameraProperties::EXPOSURE_MODE));
3388     p.set(TICameraParameters::KEY_ISO, mCameraProperties->get(CameraProperties::ISO_MODE));
3389     p.set(TICameraParameters::KEY_IPP, mCameraProperties->get(CameraProperties::IPP));
3390     p.set(TICameraParameters::KEY_GBCE, mCameraProperties->get(CameraProperties::GBCE));
3391     p.set(TICameraParameters::KEY_S3D2D_PREVIEW, mCameraProperties->get(CameraProperties::S3D2D_PREVIEW));
3392     p.set(TICameraParameters::KEY_AUTOCONVERGENCE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE));
3393     p.set(TICameraParameters::KEY_MANUALCONVERGENCE_VALUES, mCameraProperties->get(CameraProperties::MANUALCONVERGENCE_VALUES));
3394     p.set(CameraParameters::KEY_VIDEO_STABILIZATION, mCameraProperties->get(CameraProperties::VSTAB));
3395     p.set(CameraParameters::KEY_FOCAL_LENGTH, mCameraProperties->get(CameraProperties::FOCAL_LENGTH));
3396     p.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::HOR_ANGLE));
3397     p.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::VER_ANGLE));
3398     p.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
3399     p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
3400     p.set(TICameraParameters::KEY_SENSOR_ORIENTATION_VALUES, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION_VALUES));
3401     p.set(TICameraParameters::KEY_EXIF_MAKE, mCameraProperties->get(CameraProperties::EXIF_MAKE));
3402     p.set(TICameraParameters::KEY_EXIF_MODEL, mCameraProperties->get(CameraProperties::EXIF_MODEL));
3403     p.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_QUALITY));
3404     p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar");
3405     p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, mCameraProperties->get(CameraProperties::MAX_FD_HW_FACES));
3406     p.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, mCameraProperties->get(CameraProperties::MAX_FD_SW_FACES));
3407 
3408     // Only one area a.k.a Touch AF for now.
3409     // TODO: Add support for multiple focus areas.
3410     p.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, mCameraProperties->get(CameraProperties::MAX_FOCUS_AREAS));
3411     p.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK));
3412     p.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK));
3413     p.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS, mCameraProperties->get(CameraProperties::MAX_NUM_METERING_AREAS));
3414 
3415     LOG_FUNCTION_NAME_EXIT;
3416 }
3417 
3418 /**
3419    @brief Stop a previously started preview.
3420    @param none
3421    @return none
3422 
3423  */
forceStopPreview()3424 void CameraHal::forceStopPreview()
3425 {
3426     LOG_FUNCTION_NAME;
3427 
3428     // stop bracketing if it is running
3429     stopImageBracketing();
3430 
3431     if(mDisplayAdapter.get() != NULL) {
3432         ///Stop the buffer display first
3433         mDisplayAdapter->disableDisplay();
3434     }
3435 
3436     if(mAppCallbackNotifier.get() != NULL) {
3437         //Stop the callback sending
3438         mAppCallbackNotifier->stop();
3439         mAppCallbackNotifier->flushAndReturnFrames();
3440         mAppCallbackNotifier->stopPreviewCallbacks();
3441     }
3442 
3443     if ( NULL != mCameraAdapter ) {
3444         // only need to send these control commands to state machine if we are
3445         // passed the LOADED_PREVIEW_STATE
3446         if (mCameraAdapter->getState() > CameraAdapter::LOADED_PREVIEW_STATE) {
3447            // according to javadoc...FD should be stopped in stopPreview
3448            // and application needs to call startFaceDection again
3449            // to restart FD
3450            mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
3451         }
3452 
3453         mCameraAdapter->rollbackToInitializedState();
3454 
3455     }
3456 
3457     freePreviewBufs();
3458     freePreviewDataBufs();
3459 
3460     mPreviewEnabled = false;
3461     mDisplayPaused = false;
3462     mPreviewStartInProgress = false;
3463 
3464     LOG_FUNCTION_NAME_EXIT;
3465 }
3466 
3467 /**
3468    @brief Deallocates memory for all the resources held by Camera HAL.
3469 
3470    Frees the following objects- CameraAdapter, AppCallbackNotifier, DisplayAdapter,
3471    and Memory Manager
3472 
3473    @param none
3474    @return none
3475 
3476  */
deinitialize()3477 void CameraHal::deinitialize()
3478 {
3479     LOG_FUNCTION_NAME;
3480 
3481     if ( mPreviewEnabled || mDisplayPaused ) {
3482         forceStopPreview();
3483     }
3484 
3485     mSetPreviewWindowCalled = false;
3486 
3487     if (mSensorListener.get()) {
3488         mSensorListener->disableSensor(SensorListener::SENSOR_ORIENTATION);
3489         mSensorListener.clear();
3490         mSensorListener = NULL;
3491     }
3492 
3493     LOG_FUNCTION_NAME_EXIT;
3494 
3495 }
3496 
storeMetaDataInBuffers(bool enable)3497 status_t CameraHal::storeMetaDataInBuffers(bool enable)
3498 {
3499     LOG_FUNCTION_NAME;
3500 
3501     return mAppCallbackNotifier->useMetaDataBufferMode(enable);
3502 
3503     LOG_FUNCTION_NAME_EXIT;
3504 }
3505 
selectFPSRange(int framerate,int * min_fps,int * max_fps)3506 void CameraHal::selectFPSRange(int framerate, int *min_fps, int *max_fps)
3507 {
3508   char * ptr;
3509   char supported[MAX_PROP_VALUE_LENGTH];
3510   int fpsrangeArray[2];
3511   int i = 0;
3512 
3513   LOG_FUNCTION_NAME;
3514   size_t size = strlen(mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED))+1;
3515   strncpy(supported, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED), size);
3516 
3517   ptr = strtok (supported," (,)");
3518 
3519   while (ptr != NULL)
3520     {
3521       fpsrangeArray[i]= atoi(ptr)/CameraHal::VFR_SCALE;
3522       if (i == 1)
3523         {
3524           if (framerate == fpsrangeArray[i])
3525             {
3526               CAMHAL_LOGDB("SETTING FPS RANGE min = %d max = %d \n", fpsrangeArray[0], fpsrangeArray[1]);
3527               *min_fps = fpsrangeArray[0]*CameraHal::VFR_SCALE;
3528               *max_fps = fpsrangeArray[1]*CameraHal::VFR_SCALE;
3529               break;
3530             }
3531         }
3532       ptr = strtok (NULL, " (,)");
3533       i++;
3534       i%=2;
3535     }
3536 
3537   LOG_FUNCTION_NAME_EXIT;
3538 
3539 }
3540 
setPreferredPreviewRes(int width,int height)3541 void CameraHal::setPreferredPreviewRes(int width, int height)
3542 {
3543   LOG_FUNCTION_NAME;
3544 
3545   if ( (width == 320) && (height == 240)){
3546     mParameters.setPreviewSize(640,480);
3547   }
3548   if ( (width == 176) && (height == 144)){
3549     mParameters.setPreviewSize(704,576);
3550   }
3551 
3552   LOG_FUNCTION_NAME_EXIT;
3553 }
3554 
resetPreviewRes(CameraParameters * mParams,int width,int height)3555 void CameraHal::resetPreviewRes(CameraParameters *mParams, int width, int height)
3556 {
3557   LOG_FUNCTION_NAME;
3558 
3559   if ( (width <= 320) && (height <= 240)){
3560     mParams->setPreviewSize(mVideoWidth, mVideoHeight);
3561   }
3562 
3563   LOG_FUNCTION_NAME_EXIT;
3564 }
3565 
3566 };
3567 
3568 
3569