Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS"AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 // To remove
     31 #include <cutils/properties.h>
     32 
     33 // System dependencies
     34 #include <dlfcn.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <linux/msm_ion.h>
     38 #include <stdio.h>
     39 #include <sys/ioctl.h>
     40 #define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
     41 #include MMAN_H
     42 #include <unistd.h>
     43 
     44 // Camera dependencies
     45 #include "mm_qcamera_dbg.h"
     46 #include "mm_qcamera_app.h"
     47 
     48 static pthread_mutex_t app_mutex;
     49 static int thread_status = 0;
     50 static pthread_cond_t app_cond_v;
     51 
     52 #define MM_QCAMERA_APP_NANOSEC_SCALE 1000000000
     53 
     54 int mm_camera_app_timedwait(uint8_t seconds)
     55 {
     56     int rc = 0;
     57     pthread_mutex_lock(&app_mutex);
     58     if(FALSE == thread_status) {
     59         struct timespec tw;
     60         memset(&tw, 0, sizeof tw);
     61         tw.tv_sec = 0;
     62         tw.tv_nsec = time(0) + seconds * MM_QCAMERA_APP_NANOSEC_SCALE;
     63 
     64         rc = pthread_cond_timedwait(&app_cond_v, &app_mutex,&tw);
     65         thread_status = FALSE;
     66     }
     67     pthread_mutex_unlock(&app_mutex);
     68     return rc;
     69 }
     70 
     71 int mm_camera_app_wait()
     72 {
     73     int rc = 0;
     74     pthread_mutex_lock(&app_mutex);
     75     if(FALSE == thread_status){
     76         pthread_cond_wait(&app_cond_v, &app_mutex);
     77     }
     78     thread_status = FALSE;
     79     pthread_mutex_unlock(&app_mutex);
     80     return rc;
     81 }
     82 
     83 void mm_camera_app_done()
     84 {
     85   pthread_mutex_lock(&app_mutex);
     86   thread_status = TRUE;
     87   pthread_cond_signal(&app_cond_v);
     88   pthread_mutex_unlock(&app_mutex);
     89 }
     90 
     91 int mm_app_load_hal(mm_camera_app_t *my_cam_app)
     92 {
     93     memset(&my_cam_app->hal_lib, 0, sizeof(hal_interface_lib_t));
     94     my_cam_app->hal_lib.ptr = dlopen("libmmcamera_interface.so", RTLD_NOW);
     95     my_cam_app->hal_lib.ptr_jpeg = dlopen("libmmjpeg_interface.so", RTLD_NOW);
     96     if (!my_cam_app->hal_lib.ptr || !my_cam_app->hal_lib.ptr_jpeg) {
     97         LOGE("Error opening HAL library %s\n",  dlerror());
     98         return -MM_CAMERA_E_GENERAL;
     99     }
    100     *(void **)&(my_cam_app->hal_lib.get_num_of_cameras) =
    101         dlsym(my_cam_app->hal_lib.ptr, "get_num_of_cameras");
    102     *(void **)&(my_cam_app->hal_lib.mm_camera_open) =
    103         dlsym(my_cam_app->hal_lib.ptr, "camera_open");
    104     *(void **)&(my_cam_app->hal_lib.jpeg_open) =
    105         dlsym(my_cam_app->hal_lib.ptr_jpeg, "jpeg_open");
    106 
    107     if (my_cam_app->hal_lib.get_num_of_cameras == NULL ||
    108         my_cam_app->hal_lib.mm_camera_open == NULL ||
    109         my_cam_app->hal_lib.jpeg_open == NULL) {
    110         LOGE("Error loading HAL sym %s\n",  dlerror());
    111         return -MM_CAMERA_E_GENERAL;
    112     }
    113 
    114     my_cam_app->num_cameras = my_cam_app->hal_lib.get_num_of_cameras();
    115     LOGD("num_cameras = %d\n",  my_cam_app->num_cameras);
    116 
    117     return MM_CAMERA_OK;
    118 }
    119 
    120 int mm_app_allocate_ion_memory(mm_camera_app_buf_t *buf,
    121         __unused unsigned int ion_type)
    122 {
    123     int rc = MM_CAMERA_OK;
    124     struct ion_handle_data handle_data;
    125     struct ion_allocation_data alloc;
    126     struct ion_fd_data ion_info_fd;
    127     int main_ion_fd = -1;
    128     void *data = NULL;
    129 
    130     main_ion_fd = open("/dev/ion", O_RDONLY);
    131     if (main_ion_fd <= 0) {
    132         LOGE("Ion dev open failed %s\n", strerror(errno));
    133         goto ION_OPEN_FAILED;
    134     }
    135 
    136     memset(&alloc, 0, sizeof(alloc));
    137     alloc.len = buf->mem_info.size;
    138     /* to make it page size aligned */
    139     alloc.len = (alloc.len + 4095U) & (~4095U);
    140     alloc.align = 4096;
    141     alloc.flags = ION_FLAG_CACHED;
    142     alloc.heap_id_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
    143     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
    144     if (rc < 0) {
    145         LOGE("ION allocation failed %s with rc = %d \n",strerror(errno), rc);
    146         goto ION_ALLOC_FAILED;
    147     }
    148 
    149     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    150     ion_info_fd.handle = alloc.handle;
    151     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
    152     if (rc < 0) {
    153         LOGE("ION map failed %s\n", strerror(errno));
    154         goto ION_MAP_FAILED;
    155     }
    156 
    157     data = mmap(NULL,
    158                 alloc.len,
    159                 PROT_READ  | PROT_WRITE,
    160                 MAP_SHARED,
    161                 ion_info_fd.fd,
    162                 0);
    163 
    164     if (data == MAP_FAILED) {
    165         LOGE("ION_MMAP_FAILED: %s (%d)\n", strerror(errno), errno);
    166         goto ION_MAP_FAILED;
    167     }
    168     buf->mem_info.main_ion_fd = main_ion_fd;
    169     buf->mem_info.fd = ion_info_fd.fd;
    170     buf->mem_info.handle = ion_info_fd.handle;
    171     buf->mem_info.size = alloc.len;
    172     buf->mem_info.data = data;
    173     return MM_CAMERA_OK;
    174 
    175 ION_MAP_FAILED:
    176     memset(&handle_data, 0, sizeof(handle_data));
    177     handle_data.handle = ion_info_fd.handle;
    178     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
    179 ION_ALLOC_FAILED:
    180     close(main_ion_fd);
    181 ION_OPEN_FAILED:
    182     return -MM_CAMERA_E_GENERAL;
    183 }
    184 
    185 int mm_app_deallocate_ion_memory(mm_camera_app_buf_t *buf)
    186 {
    187   struct ion_handle_data handle_data;
    188   int rc = 0;
    189 
    190   rc = munmap(buf->mem_info.data, buf->mem_info.size);
    191 
    192   if (buf->mem_info.fd >= 0) {
    193       close(buf->mem_info.fd);
    194       buf->mem_info.fd = -1;
    195   }
    196 
    197   if (buf->mem_info.main_ion_fd >= 0) {
    198       memset(&handle_data, 0, sizeof(handle_data));
    199       handle_data.handle = buf->mem_info.handle;
    200       ioctl(buf->mem_info.main_ion_fd, ION_IOC_FREE, &handle_data);
    201       close(buf->mem_info.main_ion_fd);
    202       buf->mem_info.main_ion_fd = -1;
    203   }
    204   return rc;
    205 }
    206 
    207 /* cmd = ION_IOC_CLEAN_CACHES, ION_IOC_INV_CACHES, ION_IOC_CLEAN_INV_CACHES */
    208 int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info,
    209                      int cmd)
    210 {
    211     struct ion_flush_data cache_inv_data;
    212     struct ion_custom_data custom_data;
    213     int ret = MM_CAMERA_OK;
    214 
    215 #ifdef USE_ION
    216     if (NULL == mem_info) {
    217         LOGE("mem_info is NULL, return here");
    218         return -MM_CAMERA_E_GENERAL;
    219     }
    220 
    221     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
    222     memset(&custom_data, 0, sizeof(custom_data));
    223     cache_inv_data.vaddr = mem_info->data;
    224     cache_inv_data.fd = mem_info->fd;
    225     cache_inv_data.handle = mem_info->handle;
    226     cache_inv_data.length = (unsigned int)mem_info->size;
    227     custom_data.cmd = (unsigned int)cmd;
    228     custom_data.arg = (unsigned long)&cache_inv_data;
    229 
    230     LOGD("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
    231          cache_inv_data.vaddr, cache_inv_data.fd,
    232          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
    233          mem_info->main_ion_fd);
    234     if(mem_info->main_ion_fd >= 0) {
    235         if(ioctl(mem_info->main_ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
    236             LOGE("Cache Invalidate failed\n");
    237             ret = -MM_CAMERA_E_GENERAL;
    238         }
    239     }
    240 #endif
    241 
    242     return ret;
    243 }
    244 
    245 void mm_app_dump_frame(mm_camera_buf_def_t *frame,
    246                        char *name,
    247                        char *ext,
    248                        uint32_t frame_idx)
    249 {
    250     char file_name[FILENAME_MAX];
    251     int file_fd;
    252     int i;
    253     int offset = 0;
    254     if ( frame != NULL) {
    255         snprintf(file_name, sizeof(file_name),
    256                 QCAMERA_DUMP_FRM_LOCATION"%s_%04d.%s", name, frame_idx, ext);
    257         file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
    258         if (file_fd < 0) {
    259             LOGE("cannot open file %s \n",  file_name);
    260         } else {
    261             for (i = 0; i < frame->planes_buf.num_planes; i++) {
    262                 LOGD("saving file from address: %p, data offset: %d, "
    263                      "length: %d \n",  frame->buffer,
    264                     frame->planes_buf.planes[i].data_offset, frame->planes_buf.planes[i].length);
    265                 write(file_fd,
    266                       (uint8_t *)frame->buffer + offset,
    267                       frame->planes_buf.planes[i].length);
    268                 offset += (int)frame->planes_buf.planes[i].length;
    269             }
    270 
    271             close(file_fd);
    272             LOGD("dump %s", file_name);
    273         }
    274     }
    275 }
    276 
    277 void mm_app_dump_jpeg_frame(const void * data, size_t size, char* name,
    278         char* ext, uint32_t index)
    279 {
    280     char buf[FILENAME_MAX];
    281     int file_fd;
    282     if ( data != NULL) {
    283         snprintf(buf, sizeof(buf),
    284                 QCAMERA_DUMP_FRM_LOCATION"test/%s_%u.%s", name, index, ext);
    285         LOGD("%s size =%zu, jobId=%u",  buf, size, index);
    286         file_fd = open(buf, O_RDWR | O_CREAT, 0777);
    287         write(file_fd, data, size);
    288         close(file_fd);
    289     }
    290 }
    291 
    292 int mm_app_alloc_bufs(mm_camera_app_buf_t* app_bufs,
    293                       cam_frame_len_offset_t *frame_offset_info,
    294                       uint8_t num_bufs,
    295                       uint8_t is_streambuf,
    296                       size_t multipleOf)
    297 {
    298     uint32_t i, j;
    299     unsigned int ion_type = 0x1 << CAMERA_ION_FALLBACK_HEAP_ID;
    300 
    301     if (is_streambuf) {
    302         ion_type |= 0x1 << CAMERA_ION_HEAP_ID;
    303     }
    304 
    305     for (i = 0; i < num_bufs ; i++) {
    306         if ( 0 < multipleOf ) {
    307             size_t m = frame_offset_info->frame_len / multipleOf;
    308             if ( ( frame_offset_info->frame_len % multipleOf ) != 0 ) {
    309                 m++;
    310             }
    311             app_bufs[i].mem_info.size = m * multipleOf;
    312         } else {
    313             app_bufs[i].mem_info.size = frame_offset_info->frame_len;
    314         }
    315         mm_app_allocate_ion_memory(&app_bufs[i], ion_type);
    316 
    317         app_bufs[i].buf.buf_idx = i;
    318         app_bufs[i].buf.planes_buf.num_planes = (int8_t)frame_offset_info->num_planes;
    319         app_bufs[i].buf.fd = app_bufs[i].mem_info.fd;
    320         app_bufs[i].buf.frame_len = app_bufs[i].mem_info.size;
    321         app_bufs[i].buf.buffer = app_bufs[i].mem_info.data;
    322         app_bufs[i].buf.mem_info = (void *)&app_bufs[i].mem_info;
    323 
    324         /* Plane 0 needs to be set seperately. Set other planes
    325              * in a loop. */
    326         app_bufs[i].buf.planes_buf.planes[0].length = frame_offset_info->mp[0].len;
    327         app_bufs[i].buf.planes_buf.planes[0].m.userptr =
    328             (long unsigned int)app_bufs[i].buf.fd;
    329         app_bufs[i].buf.planes_buf.planes[0].data_offset = frame_offset_info->mp[0].offset;
    330         app_bufs[i].buf.planes_buf.planes[0].reserved[0] = 0;
    331         for (j = 1; j < (uint8_t)frame_offset_info->num_planes; j++) {
    332             app_bufs[i].buf.planes_buf.planes[j].length = frame_offset_info->mp[j].len;
    333             app_bufs[i].buf.planes_buf.planes[j].m.userptr =
    334                 (long unsigned int)app_bufs[i].buf.fd;
    335             app_bufs[i].buf.planes_buf.planes[j].data_offset = frame_offset_info->mp[j].offset;
    336             app_bufs[i].buf.planes_buf.planes[j].reserved[0] =
    337                 app_bufs[i].buf.planes_buf.planes[j-1].reserved[0] +
    338                 app_bufs[i].buf.planes_buf.planes[j-1].length;
    339         }
    340     }
    341     LOGD("X");
    342     return MM_CAMERA_OK;
    343 }
    344 
    345 int mm_app_release_bufs(uint8_t num_bufs,
    346                         mm_camera_app_buf_t* app_bufs)
    347 {
    348     int i, rc = MM_CAMERA_OK;
    349 
    350     LOGD("E");
    351 
    352     for (i = 0; i < num_bufs; i++) {
    353         rc = mm_app_deallocate_ion_memory(&app_bufs[i]);
    354     }
    355     memset(app_bufs, 0, num_bufs * sizeof(mm_camera_app_buf_t));
    356     LOGD("X");
    357     return rc;
    358 }
    359 
    360 int mm_app_stream_initbuf(cam_frame_len_offset_t *frame_offset_info,
    361                           uint8_t *num_bufs,
    362                           uint8_t **initial_reg_flag,
    363                           mm_camera_buf_def_t **bufs,
    364                           mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    365                           void *user_data)
    366 {
    367     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
    368     mm_camera_buf_def_t *pBufs = NULL;
    369     uint8_t *reg_flags = NULL;
    370     int i, rc;
    371 
    372     stream->offset = *frame_offset_info;
    373 
    374     LOGD("alloc buf for stream_id %d, len=%d, num planes: %d, offset: %d",
    375          stream->s_id,
    376          frame_offset_info->frame_len,
    377          frame_offset_info->num_planes,
    378          frame_offset_info->mp[1].offset);
    379 
    380     if (stream->num_of_bufs > CAM_MAX_NUM_BUFS_PER_STREAM)
    381         stream->num_of_bufs = CAM_MAX_NUM_BUFS_PER_STREAM;
    382 
    383     pBufs = (mm_camera_buf_def_t *)malloc(sizeof(mm_camera_buf_def_t) * stream->num_of_bufs);
    384     reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * stream->num_of_bufs);
    385     if (pBufs == NULL || reg_flags == NULL) {
    386         LOGE("No mem for bufs");
    387         if (pBufs != NULL) {
    388             free(pBufs);
    389         }
    390         if (reg_flags != NULL) {
    391             free(reg_flags);
    392         }
    393         return -1;
    394     }
    395 
    396     rc = mm_app_alloc_bufs(&stream->s_bufs[0],
    397                            frame_offset_info,
    398                            stream->num_of_bufs,
    399                            1,
    400                            stream->multipleOf);
    401 
    402     if (rc != MM_CAMERA_OK) {
    403         LOGE("mm_stream_alloc_bufs err = %d",  rc);
    404         free(pBufs);
    405         free(reg_flags);
    406         return rc;
    407     }
    408 
    409     for (i = 0; i < stream->num_of_bufs; i++) {
    410         /* mapping stream bufs first */
    411         pBufs[i] = stream->s_bufs[i].buf;
    412         reg_flags[i] = 1;
    413         rc = ops_tbl->map_ops(pBufs[i].buf_idx,
    414                               -1,
    415                               pBufs[i].fd,
    416                               (uint32_t)pBufs[i].frame_len,
    417                               NULL,
    418                               CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
    419         if (rc != MM_CAMERA_OK) {
    420             LOGE("mapping buf[%d] err = %d",  i, rc);
    421             break;
    422         }
    423     }
    424 
    425     if (rc != MM_CAMERA_OK) {
    426         int j;
    427         for (j=0; j>i; j++) {
    428             ops_tbl->unmap_ops(pBufs[j].buf_idx, -1,
    429                     CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
    430         }
    431         mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]);
    432         free(pBufs);
    433         free(reg_flags);
    434         return rc;
    435     }
    436 
    437     *num_bufs = stream->num_of_bufs;
    438     *bufs = pBufs;
    439     *initial_reg_flag = reg_flags;
    440 
    441     LOGD("X");
    442     return rc;
    443 }
    444 
    445 int32_t mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t *ops_tbl,
    446                                 void *user_data)
    447 {
    448     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
    449     int i;
    450 
    451     for (i = 0; i < stream->num_of_bufs ; i++) {
    452         /* mapping stream bufs first */
    453         ops_tbl->unmap_ops(stream->s_bufs[i].buf.buf_idx, -1,
    454                 CAM_MAPPING_BUF_TYPE_STREAM_BUF, ops_tbl->userdata);
    455     }
    456 
    457     mm_app_release_bufs(stream->num_of_bufs, &stream->s_bufs[0]);
    458 
    459     LOGD("X");
    460     return 0;
    461 }
    462 
    463 int32_t mm_app_stream_clean_invalidate_buf(uint32_t index, void *user_data)
    464 {
    465     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
    466     return mm_app_cache_ops(&stream->s_bufs[index].mem_info,
    467       ION_IOC_CLEAN_INV_CACHES);
    468 }
    469 
    470 int32_t mm_app_stream_invalidate_buf(uint32_t index, void *user_data)
    471 {
    472     mm_camera_stream_t *stream = (mm_camera_stream_t *)user_data;
    473     return mm_app_cache_ops(&stream->s_bufs[index].mem_info, ION_IOC_INV_CACHES);
    474 }
    475 
    476 static void notify_evt_cb(uint32_t camera_handle,
    477                           mm_camera_event_t *evt,
    478                           void *user_data)
    479 {
    480     mm_camera_test_obj_t *test_obj =
    481         (mm_camera_test_obj_t *)user_data;
    482     if (test_obj == NULL || test_obj->cam->camera_handle != camera_handle) {
    483         LOGE("Not a valid test obj");
    484         return;
    485     }
    486 
    487     LOGD("E evt = %d",  evt->server_event_type);
    488     switch (evt->server_event_type) {
    489        case CAM_EVENT_TYPE_AUTO_FOCUS_DONE:
    490            LOGD("rcvd auto focus done evt");
    491            break;
    492        case CAM_EVENT_TYPE_ZOOM_DONE:
    493            LOGD("rcvd zoom done evt");
    494            break;
    495        default:
    496            break;
    497     }
    498 
    499     LOGD("X");
    500 }
    501 
    502 int mm_app_open(mm_camera_app_t *cam_app,
    503                 int cam_id,
    504                 mm_camera_test_obj_t *test_obj)
    505 {
    506     int32_t rc = 0;
    507     cam_frame_len_offset_t offset_info;
    508 
    509     LOGD("BEGIN\n");
    510 
    511     rc = cam_app->hal_lib.mm_camera_open((uint8_t)cam_id, &(test_obj->cam));
    512     if(rc || !test_obj->cam) {
    513         LOGE("dev open error. rc = %d, vtbl = %p\n",  rc, test_obj->cam);
    514         return -MM_CAMERA_E_GENERAL;
    515     }
    516 
    517     LOGD("Open Camera id = %d handle = %d", cam_id, test_obj->cam->camera_handle);
    518 
    519     /* alloc ion mem for capability buf */
    520     memset(&offset_info, 0, sizeof(offset_info));
    521     offset_info.frame_len = sizeof(cam_capability_t);
    522 
    523     rc = mm_app_alloc_bufs(&test_obj->cap_buf,
    524                            &offset_info,
    525                            1,
    526                            0,
    527                            0);
    528     if (rc != MM_CAMERA_OK) {
    529         LOGE("alloc buf for capability error\n");
    530         goto error_after_cam_open;
    531     }
    532 
    533     /* mapping capability buf */
    534     rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle,
    535                                      CAM_MAPPING_BUF_TYPE_CAPABILITY,
    536                                      test_obj->cap_buf.mem_info.fd,
    537                                      test_obj->cap_buf.mem_info.size,
    538                                      NULL);
    539     if (rc != MM_CAMERA_OK) {
    540         LOGE("map for capability error\n");
    541         goto error_after_cap_buf_alloc;
    542     }
    543 
    544     /* alloc ion mem for getparm buf */
    545     memset(&offset_info, 0, sizeof(offset_info));
    546     offset_info.frame_len = sizeof(parm_buffer_t);
    547     rc = mm_app_alloc_bufs(&test_obj->parm_buf,
    548                            &offset_info,
    549                            1,
    550                            0,
    551                            0);
    552     if (rc != MM_CAMERA_OK) {
    553         LOGE("alloc buf for getparm_buf error\n");
    554         goto error_after_cap_buf_map;
    555     }
    556 
    557     /* mapping getparm buf */
    558     rc = test_obj->cam->ops->map_buf(test_obj->cam->camera_handle,
    559                                      CAM_MAPPING_BUF_TYPE_PARM_BUF,
    560                                      test_obj->parm_buf.mem_info.fd,
    561                                      test_obj->parm_buf.mem_info.size,
    562                                      NULL);
    563     if (rc != MM_CAMERA_OK) {
    564         LOGE("map getparm_buf error\n");
    565         goto error_after_getparm_buf_alloc;
    566     }
    567     test_obj->params_buffer = (parm_buffer_t*) test_obj->parm_buf.mem_info.data;
    568     LOGH("\n%s params_buffer=%p\n",test_obj->params_buffer);
    569 
    570     rc = test_obj->cam->ops->register_event_notify(test_obj->cam->camera_handle,
    571                                                    notify_evt_cb,
    572                                                    test_obj);
    573     if (rc != MM_CAMERA_OK) {
    574         LOGE("failed register_event_notify");
    575         rc = -MM_CAMERA_E_GENERAL;
    576         goto error_after_getparm_buf_map;
    577     }
    578 
    579     rc = test_obj->cam->ops->query_capability(test_obj->cam->camera_handle);
    580     if (rc != MM_CAMERA_OK) {
    581         LOGE("failed query_capability");
    582         rc = -MM_CAMERA_E_GENERAL;
    583         goto error_after_getparm_buf_map;
    584     }
    585     memset(&test_obj->jpeg_ops, 0, sizeof(mm_jpeg_ops_t));
    586     mm_dimension pic_size;
    587     memset(&pic_size, 0, sizeof(mm_dimension));
    588     pic_size.w = 4000;
    589     pic_size.h = 3000;
    590     test_obj->jpeg_hdl = cam_app->hal_lib.jpeg_open(&test_obj->jpeg_ops, NULL, pic_size, NULL);
    591     if (test_obj->jpeg_hdl == 0) {
    592         LOGE("jpeg lib open err");
    593         rc = -MM_CAMERA_E_GENERAL;
    594         goto error_after_getparm_buf_map;
    595     }
    596 
    597     return rc;
    598 
    599 error_after_getparm_buf_map:
    600     test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
    601                                   CAM_MAPPING_BUF_TYPE_PARM_BUF);
    602 error_after_getparm_buf_alloc:
    603     mm_app_release_bufs(1, &test_obj->parm_buf);
    604 error_after_cap_buf_map:
    605     test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
    606                                   CAM_MAPPING_BUF_TYPE_CAPABILITY);
    607 error_after_cap_buf_alloc:
    608     mm_app_release_bufs(1, &test_obj->cap_buf);
    609 error_after_cam_open:
    610     test_obj->cam->ops->close_camera(test_obj->cam->camera_handle);
    611     test_obj->cam = NULL;
    612     return rc;
    613 }
    614 
    615 int init_batch_update(parm_buffer_t *p_table)
    616 {
    617     int rc = MM_CAMERA_OK;
    618     LOGH("\nEnter %s\n");
    619     int32_t hal_version = CAM_HAL_V1;
    620 
    621     memset(p_table, 0, sizeof(parm_buffer_t));
    622     if(ADD_SET_PARAM_ENTRY_TO_BATCH(p_table, CAM_INTF_PARM_HAL_VERSION, hal_version)) {
    623         rc = -1;
    624     }
    625 
    626     return rc;
    627 }
    628 
    629 int commit_set_batch(mm_camera_test_obj_t *test_obj)
    630 {
    631     int rc = MM_CAMERA_OK;
    632     int i = 0;
    633 
    634     for(i = 0; i < CAM_INTF_PARM_MAX; i++){
    635         if(test_obj->params_buffer->is_valid[i])
    636             break;
    637     }
    638     if (i < CAM_INTF_PARM_MAX) {
    639         LOGH("\n set_param p_buffer =%p\n",test_obj->params_buffer);
    640         rc = test_obj->cam->ops->set_parms(test_obj->cam->camera_handle, test_obj->params_buffer);
    641     }
    642     if (rc != MM_CAMERA_OK) {
    643         LOGE("cam->ops->set_parms failed !!");
    644     }
    645     return rc;
    646 }
    647 
    648 int mm_app_close(mm_camera_test_obj_t *test_obj)
    649 {
    650     int32_t rc = MM_CAMERA_OK;
    651 
    652     if (test_obj == NULL || test_obj->cam ==NULL) {
    653         LOGE("cam not opened");
    654         return -MM_CAMERA_E_GENERAL;
    655     }
    656 
    657     /* unmap capability buf */
    658     rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
    659                                        CAM_MAPPING_BUF_TYPE_CAPABILITY);
    660     if (rc != MM_CAMERA_OK) {
    661         LOGE("unmap capability buf failed, rc=%d",  rc);
    662     }
    663 
    664     /* unmap parm buf */
    665     rc = test_obj->cam->ops->unmap_buf(test_obj->cam->camera_handle,
    666                                        CAM_MAPPING_BUF_TYPE_PARM_BUF);
    667     if (rc != MM_CAMERA_OK) {
    668         LOGE("unmap setparm buf failed, rc=%d",  rc);
    669     }
    670 
    671     rc = test_obj->cam->ops->close_camera(test_obj->cam->camera_handle);
    672     if (rc != MM_CAMERA_OK) {
    673         LOGE("close camera failed, rc=%d",  rc);
    674     }
    675     test_obj->cam = NULL;
    676 
    677     /* close jpeg client */
    678     if (test_obj->jpeg_hdl && test_obj->jpeg_ops.close) {
    679         rc = test_obj->jpeg_ops.close(test_obj->jpeg_hdl);
    680         test_obj->jpeg_hdl = 0;
    681         if (rc != MM_CAMERA_OK) {
    682             LOGE("close jpeg failed, rc=%d",  rc);
    683         }
    684     }
    685 
    686     /* dealloc capability buf */
    687     rc = mm_app_release_bufs(1, &test_obj->cap_buf);
    688     if (rc != MM_CAMERA_OK) {
    689         LOGE("release capability buf failed, rc=%d",  rc);
    690     }
    691 
    692     /* dealloc parm buf */
    693     rc = mm_app_release_bufs(1, &test_obj->parm_buf);
    694     if (rc != MM_CAMERA_OK) {
    695         LOGE("release setparm buf failed, rc=%d",  rc);
    696     }
    697 
    698     return MM_CAMERA_OK;
    699 }
    700 
    701 mm_camera_channel_t * mm_app_add_channel(mm_camera_test_obj_t *test_obj,
    702                                          mm_camera_channel_type_t ch_type,
    703                                          mm_camera_channel_attr_t *attr,
    704                                          mm_camera_buf_notify_t channel_cb,
    705                                          void *userdata)
    706 {
    707     uint32_t ch_id = 0;
    708     mm_camera_channel_t *channel = NULL;
    709 
    710     ch_id = test_obj->cam->ops->add_channel(test_obj->cam->camera_handle,
    711                                             attr,
    712                                             channel_cb,
    713                                             userdata);
    714     if (ch_id == 0) {
    715         LOGE("add channel failed");
    716         return NULL;
    717     }
    718     channel = &test_obj->channels[ch_type];
    719     channel->ch_id = ch_id;
    720     return channel;
    721 }
    722 
    723 int mm_app_del_channel(mm_camera_test_obj_t *test_obj,
    724                        mm_camera_channel_t *channel)
    725 {
    726     test_obj->cam->ops->delete_channel(test_obj->cam->camera_handle,
    727                                        channel->ch_id);
    728     memset(channel, 0, sizeof(mm_camera_channel_t));
    729     return MM_CAMERA_OK;
    730 }
    731 
    732 mm_camera_stream_t * mm_app_add_stream(mm_camera_test_obj_t *test_obj,
    733                                        mm_camera_channel_t *channel)
    734 {
    735     mm_camera_stream_t *stream = NULL;
    736     int rc = MM_CAMERA_OK;
    737     cam_frame_len_offset_t offset_info;
    738 
    739     stream = &(channel->streams[channel->num_streams++]);
    740     stream->s_id = test_obj->cam->ops->add_stream(test_obj->cam->camera_handle,
    741                                                   channel->ch_id);
    742     if (stream->s_id == 0) {
    743         LOGE("add stream failed");
    744         return NULL;
    745     }
    746 
    747     stream->multipleOf = test_obj->slice_size;
    748 
    749     /* alloc ion mem for stream_info buf */
    750     memset(&offset_info, 0, sizeof(offset_info));
    751     offset_info.frame_len = sizeof(cam_stream_info_t);
    752 
    753     rc = mm_app_alloc_bufs(&stream->s_info_buf,
    754                            &offset_info,
    755                            1,
    756                            0,
    757                            0);
    758     if (rc != MM_CAMERA_OK) {
    759         LOGE("alloc buf for stream_info error\n");
    760         test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
    761                                           channel->ch_id,
    762                                           stream->s_id);
    763         stream->s_id = 0;
    764         return NULL;
    765     }
    766 
    767     /* mapping streaminfo buf */
    768     rc = test_obj->cam->ops->map_stream_buf(test_obj->cam->camera_handle,
    769                                             channel->ch_id,
    770                                             stream->s_id,
    771                                             CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    772                                             0,
    773                                             -1,
    774                                             stream->s_info_buf.mem_info.fd,
    775                                             (uint32_t)stream->s_info_buf.mem_info.size, NULL);
    776     if (rc != MM_CAMERA_OK) {
    777         LOGE("map setparm_buf error\n");
    778         mm_app_deallocate_ion_memory(&stream->s_info_buf);
    779         test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
    780                                           channel->ch_id,
    781                                           stream->s_id);
    782         stream->s_id = 0;
    783         return NULL;
    784     }
    785 
    786     return stream;
    787 }
    788 
    789 int mm_app_del_stream(mm_camera_test_obj_t *test_obj,
    790                       mm_camera_channel_t *channel,
    791                       mm_camera_stream_t *stream)
    792 {
    793     test_obj->cam->ops->unmap_stream_buf(test_obj->cam->camera_handle,
    794                                          channel->ch_id,
    795                                          stream->s_id,
    796                                          CAM_MAPPING_BUF_TYPE_STREAM_INFO,
    797                                          0,
    798                                          -1);
    799     mm_app_deallocate_ion_memory(&stream->s_info_buf);
    800     test_obj->cam->ops->delete_stream(test_obj->cam->camera_handle,
    801                                       channel->ch_id,
    802                                       stream->s_id);
    803     memset(stream, 0, sizeof(mm_camera_stream_t));
    804     return MM_CAMERA_OK;
    805 }
    806 
    807 mm_camera_channel_t *mm_app_get_channel_by_type(mm_camera_test_obj_t *test_obj,
    808                                                 mm_camera_channel_type_t ch_type)
    809 {
    810     return &test_obj->channels[ch_type];
    811 }
    812 
    813 int mm_app_config_stream(mm_camera_test_obj_t *test_obj,
    814                          mm_camera_channel_t *channel,
    815                          mm_camera_stream_t *stream,
    816                          mm_camera_stream_config_t *config)
    817 {
    818     return test_obj->cam->ops->config_stream(test_obj->cam->camera_handle,
    819                                              channel->ch_id,
    820                                              stream->s_id,
    821                                              config);
    822 }
    823 
    824 int mm_app_start_channel(mm_camera_test_obj_t *test_obj,
    825                          mm_camera_channel_t *channel)
    826 {
    827     return test_obj->cam->ops->start_channel(test_obj->cam->camera_handle,
    828                                              channel->ch_id);
    829 }
    830 
    831 int mm_app_stop_channel(mm_camera_test_obj_t *test_obj,
    832                         mm_camera_channel_t *channel)
    833 {
    834     return test_obj->cam->ops->stop_channel(test_obj->cam->camera_handle,
    835                                             channel->ch_id);
    836 }
    837 
    838 int initBatchUpdate(mm_camera_test_obj_t *test_obj)
    839 {
    840     int32_t hal_version = CAM_HAL_V1;
    841 
    842     parm_buffer_t *parm_buf = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data;
    843     memset(parm_buf, 0, sizeof(parm_buffer_t));
    844     ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
    845             CAM_INTF_PARM_HAL_VERSION, hal_version);
    846 
    847     return MM_CAMERA_OK;
    848 }
    849 
    850 int commitSetBatch(mm_camera_test_obj_t *test_obj)
    851 {
    852     int rc = MM_CAMERA_OK;
    853     int i = 0;
    854 
    855     parm_buffer_t *p_table = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data;
    856     for(i = 0; i < CAM_INTF_PARM_MAX; i++){
    857         if(p_table->is_valid[i])
    858             break;
    859     }
    860     if (i < CAM_INTF_PARM_MAX) {
    861         rc = test_obj->cam->ops->set_parms(test_obj->cam->camera_handle, p_table);
    862     }
    863     return rc;
    864 }
    865 
    866 
    867 int commitGetBatch(mm_camera_test_obj_t *test_obj)
    868 {
    869     int rc = MM_CAMERA_OK;
    870     int i = 0;
    871     parm_buffer_t *p_table = ( parm_buffer_t * ) test_obj->parm_buf.mem_info.data;
    872     for(i = 0; i < CAM_INTF_PARM_MAX; i++){
    873         if(p_table->is_valid[i])
    874             break;
    875     }
    876     if (i < CAM_INTF_PARM_MAX) {
    877         rc = test_obj->cam->ops->get_parms(test_obj->cam->camera_handle, p_table);
    878     }
    879     return rc;
    880 }
    881 
    882 int setAecLock(mm_camera_test_obj_t *test_obj, int value)
    883 {
    884     int rc = MM_CAMERA_OK;
    885 
    886     rc = initBatchUpdate(test_obj);
    887     if (rc != MM_CAMERA_OK) {
    888         LOGE("Batch camera parameter update failed\n");
    889         goto ERROR;
    890     }
    891 
    892     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
    893             CAM_INTF_PARM_AEC_LOCK, (uint32_t)value)) {
    894         LOGE("AEC Lock parameter not added to batch\n");
    895         rc = -1;
    896         goto ERROR;
    897     }
    898 
    899     rc = commitSetBatch(test_obj);
    900     if (rc != MM_CAMERA_OK) {
    901         LOGE("Batch parameters commit failed\n");
    902         goto ERROR;
    903     }
    904 
    905 ERROR:
    906     return rc;
    907 }
    908 
    909 int setAwbLock(mm_camera_test_obj_t *test_obj, int value)
    910 {
    911     int rc = MM_CAMERA_OK;
    912 
    913     rc = initBatchUpdate(test_obj);
    914     if (rc != MM_CAMERA_OK) {
    915         LOGE("Batch camera parameter update failed\n");
    916         goto ERROR;
    917     }
    918 
    919     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
    920             CAM_INTF_PARM_AWB_LOCK, (uint32_t)value)) {
    921         LOGE("AWB Lock parameter not added to batch\n");
    922         rc = -1;
    923         goto ERROR;
    924     }
    925 
    926     rc = commitSetBatch(test_obj);
    927     if (rc != MM_CAMERA_OK) {
    928         LOGE("Batch parameters commit failed\n");
    929         goto ERROR;
    930     }
    931 
    932 ERROR:
    933     return rc;
    934 }
    935 
    936 
    937 int set3Acommand(mm_camera_test_obj_t *test_obj, cam_eztune_cmd_data_t *value)
    938 {
    939     int rc = MM_CAMERA_OK;
    940 
    941     rc = initBatchUpdate(test_obj);
    942     if (rc != MM_CAMERA_OK) {
    943         LOGE("Batch camera parameter update failed\n");
    944         goto ERROR;
    945     }
    946 
    947     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
    948             CAM_INTF_PARM_EZTUNE_CMD, *value)) {
    949         LOGE("CAM_INTF_PARM_EZTUNE_CMD parameter not added to batch\n");
    950         rc = -1;
    951         goto ERROR;
    952     }
    953 
    954     rc = commitSetBatch(test_obj);
    955     if (rc != MM_CAMERA_OK) {
    956         LOGE("Batch parameters commit failed\n");
    957         goto ERROR;
    958     }
    959 
    960 ERROR:
    961     return rc;
    962 }
    963 
    964 int setAutoFocusTuning(mm_camera_test_obj_t *test_obj, tune_actuator_t *value)
    965 {
    966     int rc = MM_CAMERA_OK;
    967 
    968     rc = initBatchUpdate(test_obj);
    969     if (rc != MM_CAMERA_OK) {
    970         LOGE("Batch camera parameter update failed\n");
    971         goto ERROR;
    972     }
    973 
    974     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
    975             CAM_INTF_PARM_SET_AUTOFOCUSTUNING, *value)) {
    976         LOGE("AutoFocus Tuning not added to batch\n");
    977         rc = -1;
    978         goto ERROR;
    979     }
    980 
    981     rc = commitSetBatch(test_obj);
    982     if (rc != MM_CAMERA_OK) {
    983         LOGE("Batch parameters commit failed\n");
    984         goto ERROR;
    985     }
    986 
    987 ERROR:
    988     return rc;
    989 }
    990 
    991 int setVfeCommand(mm_camera_test_obj_t *test_obj, tune_cmd_t *value)
    992 {
    993     int rc = MM_CAMERA_OK;
    994 
    995     rc = initBatchUpdate(test_obj);
    996     if (rc != MM_CAMERA_OK) {
    997         LOGE("Batch camera parameter update failed\n");
    998         goto ERROR;
    999     }
   1000 
   1001     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1002             CAM_INTF_PARM_SET_VFE_COMMAND, *value)) {
   1003         LOGE("VFE Command not added to batch\n");
   1004         rc = -1;
   1005         goto ERROR;
   1006     }
   1007 
   1008     rc = commitSetBatch(test_obj);
   1009     if (rc != MM_CAMERA_OK) {
   1010         LOGE("Batch parameters commit failed\n");
   1011         goto ERROR;
   1012     }
   1013 
   1014 ERROR:
   1015     return rc;
   1016 }
   1017 
   1018 int setmetainfoCommand(mm_camera_test_obj_t *test_obj, cam_stream_size_info_t *value)
   1019 {
   1020     int rc = MM_CAMERA_OK;
   1021 
   1022     rc = initBatchUpdate(test_obj);
   1023     if (rc != MM_CAMERA_OK) {
   1024         LOGE("Batch camera parameter update failed\n");
   1025         goto ERROR;
   1026     }
   1027 
   1028     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1029             CAM_INTF_META_STREAM_INFO, *value)) {
   1030         LOGE("PP Command not added to batch\n");
   1031         rc = -1;
   1032         goto ERROR;
   1033     }
   1034 
   1035     rc = commitSetBatch(test_obj);
   1036     if (rc != MM_CAMERA_OK) {
   1037         LOGE("Batch parameters commit failed\n");
   1038         goto ERROR;
   1039     }
   1040 
   1041 ERROR:
   1042     return rc;
   1043 }
   1044 
   1045 
   1046 int setPPCommand(mm_camera_test_obj_t *test_obj, tune_cmd_t *value)
   1047 {
   1048     int rc = MM_CAMERA_OK;
   1049 
   1050     rc = initBatchUpdate(test_obj);
   1051     if (rc != MM_CAMERA_OK) {
   1052         LOGE("Batch camera parameter update failed\n");
   1053         goto ERROR;
   1054     }
   1055 
   1056     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1057             CAM_INTF_PARM_SET_PP_COMMAND, *value)) {
   1058         LOGE("PP Command not added to batch\n");
   1059         rc = -1;
   1060         goto ERROR;
   1061     }
   1062 
   1063     rc = commitSetBatch(test_obj);
   1064     if (rc != MM_CAMERA_OK) {
   1065         LOGE("Batch parameters commit failed\n");
   1066         goto ERROR;
   1067     }
   1068 
   1069 ERROR:
   1070     return rc;
   1071 }
   1072 
   1073 int setFocusMode(mm_camera_test_obj_t *test_obj, cam_focus_mode_type mode)
   1074 {
   1075     int rc = MM_CAMERA_OK;
   1076 
   1077     rc = initBatchUpdate(test_obj);
   1078     if (rc != MM_CAMERA_OK) {
   1079         LOGE("Batch camera parameter update failed\n");
   1080         goto ERROR;
   1081     }
   1082 
   1083     uint32_t value = mode;
   1084 
   1085     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1086             CAM_INTF_PARM_FOCUS_MODE, value)) {
   1087         LOGE("Focus mode parameter not added to batch\n");
   1088         rc = -1;
   1089         goto ERROR;
   1090     }
   1091 
   1092     rc = commitSetBatch(test_obj);
   1093     if (rc != MM_CAMERA_OK) {
   1094         LOGE("Batch parameters commit failed\n");
   1095         goto ERROR;
   1096     }
   1097 
   1098 ERROR:
   1099     return rc;
   1100 }
   1101 
   1102 int setEVCompensation(mm_camera_test_obj_t *test_obj, int ev)
   1103 {
   1104     int rc = MM_CAMERA_OK;
   1105 
   1106     cam_capability_t *camera_cap = NULL;
   1107 
   1108     camera_cap = (cam_capability_t *) test_obj->cap_buf.mem_info.data;
   1109     if ( (ev >= camera_cap->exposure_compensation_min) &&
   1110          (ev <= camera_cap->exposure_compensation_max) ) {
   1111 
   1112         rc = initBatchUpdate(test_obj);
   1113         if (rc != MM_CAMERA_OK) {
   1114             LOGE("Batch camera parameter update failed\n");
   1115             goto ERROR;
   1116         }
   1117 
   1118         if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1119                 CAM_INTF_PARM_EXPOSURE_COMPENSATION, ev)) {
   1120             LOGE("EV compensation parameter not added to batch\n");
   1121             rc = -1;
   1122             goto ERROR;
   1123         }
   1124 
   1125         rc = commitSetBatch(test_obj);
   1126         if (rc != MM_CAMERA_OK) {
   1127             LOGE("Batch parameters commit failed\n");
   1128             goto ERROR;
   1129         }
   1130 
   1131         LOGE("EV compensation set to: %d",  ev);
   1132     } else {
   1133         LOGE("Invalid EV compensation");
   1134         return -EINVAL;
   1135     }
   1136 
   1137 ERROR:
   1138     return rc;
   1139 }
   1140 
   1141 int setAntibanding(mm_camera_test_obj_t *test_obj, cam_antibanding_mode_type antibanding)
   1142 {
   1143     int rc = MM_CAMERA_OK;
   1144 
   1145     rc = initBatchUpdate(test_obj);
   1146     if (rc != MM_CAMERA_OK) {
   1147         LOGE("Batch camera parameter update failed\n");
   1148         goto ERROR;
   1149     }
   1150 
   1151     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1152             CAM_INTF_PARM_ANTIBANDING, antibanding)) {
   1153         LOGE("Antibanding parameter not added to batch\n");
   1154         rc = -1;
   1155         goto ERROR;
   1156     }
   1157 
   1158     rc = commitSetBatch(test_obj);
   1159     if (rc != MM_CAMERA_OK) {
   1160         LOGE("Batch parameters commit failed\n");
   1161         goto ERROR;
   1162     }
   1163 
   1164     LOGE("Antibanding set to: %d",  (int)antibanding);
   1165 
   1166 ERROR:
   1167     return rc;
   1168 }
   1169 
   1170 int setWhiteBalance(mm_camera_test_obj_t *test_obj, cam_wb_mode_type mode)
   1171 {
   1172     int rc = MM_CAMERA_OK;
   1173 
   1174     rc = initBatchUpdate(test_obj);
   1175     if (rc != MM_CAMERA_OK) {
   1176         LOGE("Batch camera parameter update failed\n");
   1177         goto ERROR;
   1178     }
   1179 
   1180     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1181             CAM_INTF_PARM_WHITE_BALANCE, mode)) {
   1182         LOGE("White balance parameter not added to batch\n");
   1183         rc = -1;
   1184         goto ERROR;
   1185     }
   1186 
   1187     rc = commitSetBatch(test_obj);
   1188     if (rc != MM_CAMERA_OK) {
   1189         LOGE("Batch parameters commit failed\n");
   1190         goto ERROR;
   1191     }
   1192 
   1193     LOGE("White balance set to: %d",  (int)mode);
   1194 
   1195 ERROR:
   1196     return rc;
   1197 }
   1198 
   1199 int setExposureMetering(mm_camera_test_obj_t *test_obj, cam_auto_exposure_mode_type mode)
   1200 {
   1201     int rc = MM_CAMERA_OK;
   1202 
   1203     rc = initBatchUpdate(test_obj);
   1204     if (rc != MM_CAMERA_OK) {
   1205         LOGE("Batch camera parameter update failed\n");
   1206         goto ERROR;
   1207     }
   1208 
   1209     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1210             CAM_INTF_PARM_EXPOSURE, mode)) {
   1211         LOGE("Exposure metering parameter not added to batch\n");
   1212         rc = -1;
   1213         goto ERROR;
   1214     }
   1215 
   1216     rc = commitSetBatch(test_obj);
   1217     if (rc != MM_CAMERA_OK) {
   1218         LOGE("Batch parameters commit failed\n");
   1219         goto ERROR;
   1220     }
   1221 
   1222     LOGE("Exposure metering set to: %d",  (int)mode);
   1223 
   1224 ERROR:
   1225     return rc;
   1226 }
   1227 
   1228 int setBrightness(mm_camera_test_obj_t *test_obj, int brightness)
   1229 {
   1230     int rc = MM_CAMERA_OK;
   1231 
   1232     rc = initBatchUpdate(test_obj);
   1233     if (rc != MM_CAMERA_OK) {
   1234         LOGE("Batch camera parameter update failed\n");
   1235         goto ERROR;
   1236     }
   1237 
   1238     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1239             CAM_INTF_PARM_BRIGHTNESS, brightness)) {
   1240         LOGE("Brightness parameter not added to batch\n");
   1241         rc = -1;
   1242         goto ERROR;
   1243     }
   1244 
   1245     rc = commitSetBatch(test_obj);
   1246     if (rc != MM_CAMERA_OK) {
   1247         LOGE("Batch parameters commit failed\n");
   1248         goto ERROR;
   1249     }
   1250 
   1251     LOGE("Brightness set to: %d",  brightness);
   1252 
   1253 ERROR:
   1254     return rc;
   1255 }
   1256 
   1257 int setContrast(mm_camera_test_obj_t *test_obj, int contrast)
   1258 {
   1259     int rc = MM_CAMERA_OK;
   1260 
   1261     rc = initBatchUpdate(test_obj);
   1262     if (rc != MM_CAMERA_OK) {
   1263         LOGE("Batch camera parameter update failed\n");
   1264         goto ERROR;
   1265     }
   1266 
   1267     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1268             CAM_INTF_PARM_CONTRAST, contrast)) {
   1269         LOGE("Contrast parameter not added to batch\n");
   1270         rc = -1;
   1271         goto ERROR;
   1272     }
   1273 
   1274     rc = commitSetBatch(test_obj);
   1275     if (rc != MM_CAMERA_OK) {
   1276         LOGE("Batch parameters commit failed\n");
   1277         goto ERROR;
   1278     }
   1279 
   1280     LOGE("Contrast set to: %d",  contrast);
   1281 
   1282 ERROR:
   1283     return rc;
   1284 }
   1285 
   1286 int setTintless(mm_camera_test_obj_t *test_obj, int tintless)
   1287 {
   1288     int rc = MM_CAMERA_OK;
   1289 
   1290     rc = initBatchUpdate(test_obj);
   1291     if (rc != MM_CAMERA_OK) {
   1292         LOGE("Batch camera parameter update failed\n");
   1293         goto ERROR;
   1294     }
   1295 
   1296     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1297             CAM_INTF_PARM_TINTLESS, tintless)) {
   1298         LOGE("Tintless parameter not added to batch\n");
   1299         rc = -1;
   1300         goto ERROR;
   1301     }
   1302 
   1303     rc = commitSetBatch(test_obj);
   1304     if (rc != MM_CAMERA_OK) {
   1305         LOGE("Batch parameters commit failed\n");
   1306         goto ERROR;
   1307     }
   1308 
   1309     LOGE("set Tintless to: %d",  tintless);
   1310 
   1311 ERROR:
   1312     return rc;
   1313 }
   1314 
   1315 int setSaturation(mm_camera_test_obj_t *test_obj, int saturation)
   1316 {
   1317     int rc = MM_CAMERA_OK;
   1318 
   1319     rc = initBatchUpdate(test_obj);
   1320     if (rc != MM_CAMERA_OK) {
   1321         LOGE("Batch camera parameter update failed\n");
   1322         goto ERROR;
   1323     }
   1324 
   1325     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1326             CAM_INTF_PARM_SATURATION, saturation)) {
   1327         LOGE("Saturation parameter not added to batch\n");
   1328         rc = -1;
   1329         goto ERROR;
   1330     }
   1331 
   1332     rc = commitSetBatch(test_obj);
   1333     if (rc != MM_CAMERA_OK) {
   1334         LOGE("Batch parameters commit failed\n");
   1335         goto ERROR;
   1336     }
   1337 
   1338     LOGE("Saturation set to: %d",  saturation);
   1339 
   1340 ERROR:
   1341     return rc;
   1342 }
   1343 
   1344 int setSharpness(mm_camera_test_obj_t *test_obj, int sharpness)
   1345 {
   1346     int rc = MM_CAMERA_OK;
   1347 
   1348     rc = initBatchUpdate(test_obj);
   1349     if (rc != MM_CAMERA_OK) {
   1350         LOGE("Batch camera parameter update failed\n");
   1351         goto ERROR;
   1352     }
   1353 
   1354     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1355             CAM_INTF_PARM_SHARPNESS, sharpness)) {
   1356         LOGE("Sharpness parameter not added to batch\n");
   1357         rc = -1;
   1358         goto ERROR;
   1359     }
   1360 
   1361     rc = commitSetBatch(test_obj);
   1362     if (rc != MM_CAMERA_OK) {
   1363         LOGE("Batch parameters commit failed\n");
   1364         goto ERROR;
   1365     }
   1366 
   1367     test_obj->reproc_sharpness = sharpness;
   1368     LOGE("Sharpness set to: %d",  sharpness);
   1369 
   1370 ERROR:
   1371     return rc;
   1372 }
   1373 
   1374 int setISO(mm_camera_test_obj_t *test_obj, cam_iso_mode_type iso)
   1375 {
   1376     int rc = MM_CAMERA_OK;
   1377 
   1378     rc = initBatchUpdate(test_obj);
   1379     if (rc != MM_CAMERA_OK) {
   1380         LOGE("Batch camera parameter update failed\n");
   1381         goto ERROR;
   1382     }
   1383 
   1384     cam_intf_parm_manual_3a_t iso_settings;
   1385     memset(&iso_settings, 0, sizeof(cam_intf_parm_manual_3a_t));
   1386     iso_settings.previewOnly = FALSE;
   1387     iso_settings.value = (uint64_t)iso;
   1388     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1389             CAM_INTF_PARM_ISO, iso_settings)) {
   1390         LOGE("ISO parameter not added to batch\n");
   1391         rc = -1;
   1392         goto ERROR;
   1393     }
   1394 
   1395     rc = commitSetBatch(test_obj);
   1396     if (rc != MM_CAMERA_OK) {
   1397         LOGE("Batch parameters commit failed\n");
   1398         goto ERROR;
   1399     }
   1400 
   1401     LOGE("ISO set to: %d",  (int)iso);
   1402 
   1403 ERROR:
   1404     return rc;
   1405 }
   1406 
   1407 int setZoom(mm_camera_test_obj_t *test_obj, int zoom)
   1408 {
   1409     int rc = MM_CAMERA_OK;
   1410 
   1411     rc = initBatchUpdate(test_obj);
   1412     if (rc != MM_CAMERA_OK) {
   1413         LOGE("Batch camera parameter update failed\n");
   1414         goto ERROR;
   1415     }
   1416 
   1417     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1418             CAM_INTF_PARM_ZOOM, zoom)) {
   1419         LOGE("Zoom parameter not added to batch\n");
   1420         rc = -1;
   1421         goto ERROR;
   1422     }
   1423 
   1424     rc = commitSetBatch(test_obj);
   1425     if (rc != MM_CAMERA_OK) {
   1426         LOGE("Batch parameters commit failed\n");
   1427         goto ERROR;
   1428     }
   1429 
   1430     LOGE("Zoom set to: %d",  zoom);
   1431 
   1432 ERROR:
   1433     return rc;
   1434 }
   1435 
   1436 int setFPSRange(mm_camera_test_obj_t *test_obj, cam_fps_range_t range)
   1437 {
   1438     int rc = MM_CAMERA_OK;
   1439 
   1440     rc = initBatchUpdate(test_obj);
   1441     if (rc != MM_CAMERA_OK) {
   1442         LOGE("Batch camera parameter update failed\n");
   1443         goto ERROR;
   1444     }
   1445 
   1446     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1447             CAM_INTF_PARM_FPS_RANGE, range)) {
   1448         LOGE("FPS range parameter not added to batch\n");
   1449         rc = -1;
   1450         goto ERROR;
   1451     }
   1452 
   1453     rc = commitSetBatch(test_obj);
   1454     if (rc != MM_CAMERA_OK) {
   1455         LOGE("Batch parameters commit failed\n");
   1456         goto ERROR;
   1457     }
   1458 
   1459     LOGE("FPS Range set to: [%5.2f:%5.2f]",
   1460             range.min_fps,
   1461             range.max_fps);
   1462 
   1463 ERROR:
   1464     return rc;
   1465 }
   1466 
   1467 int setScene(mm_camera_test_obj_t *test_obj, cam_scene_mode_type scene)
   1468 {
   1469     int rc = MM_CAMERA_OK;
   1470 
   1471     rc = initBatchUpdate(test_obj);
   1472     if (rc != MM_CAMERA_OK) {
   1473         LOGE("Batch camera parameter update failed\n");
   1474         goto ERROR;
   1475     }
   1476 
   1477     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1478             CAM_INTF_PARM_BESTSHOT_MODE, scene)) {
   1479         LOGE("Scene parameter not added to batch\n");
   1480         rc = -1;
   1481         goto ERROR;
   1482     }
   1483 
   1484     rc = commitSetBatch(test_obj);
   1485     if (rc != MM_CAMERA_OK) {
   1486         LOGE("Batch parameters commit failed\n");
   1487         goto ERROR;
   1488     }
   1489 
   1490     LOGE("Scene set to: %d",  (int)scene);
   1491 
   1492 ERROR:
   1493     return rc;
   1494 }
   1495 
   1496 int setFlash(mm_camera_test_obj_t *test_obj, cam_flash_mode_t flash)
   1497 {
   1498     int rc = MM_CAMERA_OK;
   1499 
   1500     rc = initBatchUpdate(test_obj);
   1501     if (rc != MM_CAMERA_OK) {
   1502         LOGE("Batch camera parameter update failed\n");
   1503         goto ERROR;
   1504     }
   1505 
   1506     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1507             CAM_INTF_PARM_LED_MODE, flash)) {
   1508         LOGE("Flash parameter not added to batch\n");
   1509         rc = -1;
   1510         goto ERROR;
   1511     }
   1512 
   1513     rc = commitSetBatch(test_obj);
   1514     if (rc != MM_CAMERA_OK) {
   1515         LOGE("Batch parameters commit failed\n");
   1516         goto ERROR;
   1517     }
   1518 
   1519     LOGE("Flash set to: %d",  (int)flash);
   1520 
   1521 ERROR:
   1522     return rc;
   1523 }
   1524 
   1525 int setWNR(mm_camera_test_obj_t *test_obj, uint8_t enable)
   1526 {
   1527     int rc = MM_CAMERA_OK;
   1528 
   1529     rc = initBatchUpdate(test_obj);
   1530     if (rc != MM_CAMERA_OK) {
   1531         LOGE("Batch camera parameter update failed\n");
   1532         goto ERROR;
   1533     }
   1534 
   1535     cam_denoise_param_t param;
   1536     memset(&param, 0, sizeof(cam_denoise_param_t));
   1537     param.denoise_enable = enable;
   1538     param.process_plates = CAM_WAVELET_DENOISE_YCBCR_PLANE;
   1539 
   1540     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   1541             CAM_INTF_PARM_WAVELET_DENOISE, param)) {
   1542         LOGE("WNR enabled parameter not added to batch\n");
   1543         rc = -1;
   1544         goto ERROR;
   1545     }
   1546 
   1547     rc = commitSetBatch(test_obj);
   1548     if (rc != MM_CAMERA_OK) {
   1549         LOGE("Batch parameters commit failed\n");
   1550         goto ERROR;
   1551     }
   1552 
   1553 
   1554     test_obj->reproc_wnr = param;
   1555     LOGE("WNR enabled: %d",  enable);
   1556 
   1557 ERROR:
   1558     return rc;
   1559 }
   1560 
   1561 
   1562 /** tuneserver_capture
   1563  *    @lib_handle: the camera handle object
   1564  *    @dim: snapshot dimensions
   1565  *
   1566  *  makes JPEG capture
   1567  *
   1568  *  Return: >=0 on success, -1 on failure.
   1569  **/
   1570 int tuneserver_capture(mm_camera_lib_handle *lib_handle,
   1571                        mm_camera_lib_snapshot_params *dim)
   1572 {
   1573     int rc = 0;
   1574 
   1575     printf("Take jpeg snapshot\n");
   1576     if ( lib_handle->stream_running ) {
   1577 
   1578         if ( lib_handle->test_obj.zsl_enabled) {
   1579             if ( NULL != dim) {
   1580                 if ( ( lib_handle->test_obj.buffer_width != dim->width) ||
   1581                      ( lib_handle->test_obj.buffer_height = dim->height ) ) {
   1582 
   1583                     lib_handle->test_obj.buffer_width = dim->width;
   1584                     lib_handle->test_obj.buffer_height = dim->height;
   1585 
   1586                     rc = mm_camera_lib_stop_stream(lib_handle);
   1587                     if (rc != MM_CAMERA_OK) {
   1588                         LOGE("mm_camera_lib_stop_stream() err=%d\n",
   1589                                     rc);
   1590                         goto EXIT;
   1591                     }
   1592 
   1593                     rc = mm_camera_lib_start_stream(lib_handle);
   1594                     if (rc != MM_CAMERA_OK) {
   1595                         LOGE("mm_camera_lib_start_stream() err=%d\n",
   1596                                     rc);
   1597                         goto EXIT;
   1598                     }
   1599                 }
   1600 
   1601             }
   1602 
   1603             lib_handle->test_obj.encodeJpeg = 1;
   1604 
   1605             mm_camera_app_wait();
   1606         } else {
   1607             // For standard 2D capture streaming has to be disabled first
   1608             rc = mm_camera_lib_stop_stream(lib_handle);
   1609             if (rc != MM_CAMERA_OK) {
   1610                 LOGE("mm_camera_lib_stop_stream() err=%d\n",
   1611                           rc);
   1612                 goto EXIT;
   1613             }
   1614 
   1615             if ( NULL != dim ) {
   1616                 lib_handle->test_obj.buffer_width = dim->width;
   1617                 lib_handle->test_obj.buffer_height = dim->height;
   1618             }
   1619             rc = mm_app_start_capture(&lib_handle->test_obj, 1);
   1620             if (rc != MM_CAMERA_OK) {
   1621                 LOGE("mm_app_start_capture() err=%d\n",
   1622                           rc);
   1623                 goto EXIT;
   1624             }
   1625 
   1626             mm_camera_app_wait();
   1627 
   1628             rc = mm_app_stop_capture(&lib_handle->test_obj);
   1629             if (rc != MM_CAMERA_OK) {
   1630                 LOGE("mm_app_stop_capture() err=%d\n",
   1631                           rc);
   1632                 goto EXIT;
   1633             }
   1634 
   1635             // Restart streaming after capture is done
   1636             rc = mm_camera_lib_start_stream(lib_handle);
   1637             if (rc != MM_CAMERA_OK) {
   1638                 LOGE("mm_camera_lib_start_stream() err=%d\n",
   1639                           rc);
   1640                 goto EXIT;
   1641             }
   1642         }
   1643     }
   1644 
   1645 EXIT:
   1646 
   1647     return rc;
   1648 }
   1649 
   1650 int mm_app_start_regression_test(int run_tc)
   1651 {
   1652     int rc = MM_CAMERA_OK;
   1653     mm_camera_app_t my_cam_app;
   1654 
   1655     LOGD("\nCamera Test Application\n");
   1656     memset(&my_cam_app, 0, sizeof(mm_camera_app_t));
   1657 
   1658     rc = mm_app_load_hal(&my_cam_app);
   1659     if (rc != MM_CAMERA_OK) {
   1660         LOGE("mm_app_load_hal failed !!");
   1661         return rc;
   1662     }
   1663 
   1664     if(run_tc) {
   1665         rc = mm_app_unit_test_entry(&my_cam_app);
   1666         return rc;
   1667     }
   1668 #if 0
   1669     if(run_dual_tc) {
   1670         printf("\tRunning Dual camera test engine only\n");
   1671         rc = mm_app_dual_test_entry(&my_cam_app);
   1672         printf("\t Dual camera engine. EXIT(%d)!!!\n", rc);
   1673         exit(rc);
   1674     }
   1675 #endif
   1676     return rc;
   1677 }
   1678 
   1679 int32_t mm_camera_load_tuninglibrary(mm_camera_tuning_lib_params_t *tuning_param)
   1680 {
   1681   void *(*tuning_open_lib)(void) = NULL;
   1682 
   1683   LOGD("E");
   1684   tuning_param->lib_handle = dlopen("libmmcamera_tuning.so", RTLD_NOW);
   1685   if (!tuning_param->lib_handle) {
   1686     LOGE("Failed opening libmmcamera_tuning.so\n");
   1687     return -EINVAL;
   1688   }
   1689 
   1690   *(void **)&tuning_open_lib  = dlsym(tuning_param->lib_handle,
   1691     "open_tuning_lib");
   1692   if (!tuning_open_lib) {
   1693     LOGE("Failed symbol libmmcamera_tuning.so\n");
   1694     return -EINVAL;
   1695   }
   1696 
   1697   if (tuning_param->func_tbl) {
   1698     LOGE("already loaded tuninglib..");
   1699     return 0;
   1700   }
   1701 
   1702   tuning_param->func_tbl = (mm_camera_tune_func_t *)tuning_open_lib();
   1703   if (!tuning_param->func_tbl) {
   1704     LOGE("Failed opening library func table ptr\n");
   1705     return -EINVAL;
   1706   }
   1707 
   1708   LOGD("X");
   1709   return 0;
   1710 }
   1711 
   1712 int mm_camera_lib_open(mm_camera_lib_handle *handle, int cam_id)
   1713 {
   1714     int rc = MM_CAMERA_OK;
   1715 
   1716     if ( NULL == handle ) {
   1717         LOGE(" Invalid handle");
   1718         rc = MM_CAMERA_E_INVALID_INPUT;
   1719         goto EXIT;
   1720     }
   1721 
   1722     memset(handle, 0, sizeof(mm_camera_lib_handle));
   1723     rc = mm_app_load_hal(&handle->app_ctx);
   1724     if( MM_CAMERA_OK != rc ) {
   1725         LOGE("mm_app_init err\n");
   1726         goto EXIT;
   1727     }
   1728 
   1729     handle->test_obj.buffer_width = DEFAULT_PREVIEW_WIDTH;
   1730     handle->test_obj.buffer_height = DEFAULT_PREVIEW_HEIGHT;
   1731     handle->test_obj.buffer_format = DEFAULT_SNAPSHOT_FORMAT;
   1732     handle->current_params.stream_width = DEFAULT_SNAPSHOT_WIDTH;
   1733     handle->current_params.stream_height = DEFAULT_SNAPSHOT_HEIGHT;
   1734     handle->current_params.af_mode = CAM_FOCUS_MODE_AUTO; // Default to auto focus mode
   1735     rc = mm_app_open(&handle->app_ctx, (uint8_t)cam_id, &handle->test_obj);
   1736     if (rc != MM_CAMERA_OK) {
   1737         LOGE("mm_app_open() cam_idx=%d, err=%d\n",
   1738                     cam_id, rc);
   1739         goto EXIT;
   1740     }
   1741 
   1742     //rc = mm_app_initialize_fb(&handle->test_obj);
   1743     rc = MM_CAMERA_OK;
   1744     if (rc != MM_CAMERA_OK) {
   1745         LOGE("mm_app_initialize_fb() cam_idx=%d, err=%d\n",
   1746                     cam_id, rc);
   1747         goto EXIT;
   1748     }
   1749 
   1750 EXIT:
   1751 
   1752     return rc;
   1753 }
   1754 
   1755 int mm_camera_lib_start_stream(mm_camera_lib_handle *handle)
   1756 {
   1757     int rc = MM_CAMERA_OK;
   1758     cam_capability_t camera_cap;
   1759 
   1760     if ( NULL == handle ) {
   1761         LOGE(" Invalid handle");
   1762         rc = MM_CAMERA_E_INVALID_INPUT;
   1763         goto EXIT;
   1764     }
   1765 
   1766     if ( handle->test_obj.zsl_enabled ) {
   1767         rc = mm_app_start_preview_zsl(&handle->test_obj);
   1768         if (rc != MM_CAMERA_OK) {
   1769             LOGE("mm_app_start_preview_zsl() err=%d\n",
   1770                         rc);
   1771             goto EXIT;
   1772         }
   1773     } else {
   1774         handle->test_obj.enable_reproc = ENABLE_REPROCESSING;
   1775         rc = mm_app_start_preview(&handle->test_obj);
   1776         if (rc != MM_CAMERA_OK) {
   1777             LOGE("mm_app_start_preview() err=%d\n",
   1778                         rc);
   1779             goto EXIT;
   1780         }
   1781     }
   1782 
   1783     // Configure focus mode after stream starts
   1784     rc = mm_camera_lib_get_caps(handle, &camera_cap);
   1785     if ( MM_CAMERA_OK != rc ) {
   1786       LOGE("mm_camera_lib_get_caps() err=%d\n",  rc);
   1787       return -1;
   1788     }
   1789     if (camera_cap.supported_focus_modes_cnt == 1 &&
   1790       camera_cap.supported_focus_modes[0] == CAM_FOCUS_MODE_FIXED) {
   1791       LOGD("focus not supported");
   1792       handle->test_obj.focus_supported = 0;
   1793       handle->current_params.af_mode = CAM_FOCUS_MODE_FIXED;
   1794     } else {
   1795       handle->test_obj.focus_supported = 1;
   1796     }
   1797     rc = setFocusMode(&handle->test_obj, handle->current_params.af_mode);
   1798     if (rc != MM_CAMERA_OK) {
   1799       LOGE("autofocus error\n");
   1800       goto EXIT;
   1801     }
   1802     handle->stream_running = 1;
   1803 
   1804 EXIT:
   1805     return rc;
   1806 }
   1807 
   1808 int mm_camera_lib_stop_stream(mm_camera_lib_handle *handle)
   1809 {
   1810     int rc = MM_CAMERA_OK;
   1811 
   1812     if ( NULL == handle ) {
   1813         LOGE(" Invalid handle");
   1814         rc = MM_CAMERA_E_INVALID_INPUT;
   1815         goto EXIT;
   1816     }
   1817 
   1818     if ( handle->test_obj.zsl_enabled ) {
   1819         rc = mm_app_stop_preview_zsl(&handle->test_obj);
   1820         if (rc != MM_CAMERA_OK) {
   1821             LOGE("mm_app_stop_preview_zsl() err=%d\n",
   1822                         rc);
   1823             goto EXIT;
   1824         }
   1825     } else {
   1826         rc = mm_app_stop_preview(&handle->test_obj);
   1827         if (rc != MM_CAMERA_OK) {
   1828             LOGE("mm_app_stop_preview() err=%d\n",
   1829                         rc);
   1830             goto EXIT;
   1831         }
   1832     }
   1833 
   1834     handle->stream_running = 0;
   1835 
   1836 EXIT:
   1837     return rc;
   1838 }
   1839 
   1840 int mm_camera_lib_get_caps(mm_camera_lib_handle *handle,
   1841                            cam_capability_t *caps)
   1842 {
   1843     int rc = MM_CAMERA_OK;
   1844 
   1845     if ( NULL == handle ) {
   1846         LOGE(" Invalid handle");
   1847         rc = MM_CAMERA_E_INVALID_INPUT;
   1848         goto EXIT;
   1849     }
   1850 
   1851     if ( NULL == caps ) {
   1852         LOGE(" Invalid capabilities structure");
   1853         rc = MM_CAMERA_E_INVALID_INPUT;
   1854         goto EXIT;
   1855     }
   1856 
   1857     *caps = *( (cam_capability_t *) handle->test_obj.cap_buf.mem_info.data );
   1858 
   1859 EXIT:
   1860 
   1861     return rc;
   1862 }
   1863 
   1864 
   1865 int mm_camera_lib_send_command(mm_camera_lib_handle *handle,
   1866                                mm_camera_lib_commands cmd,
   1867                                void *in_data,
   1868                                __unused void *out_data)
   1869 {
   1870     uint32_t width, height;
   1871     int rc = MM_CAMERA_OK;
   1872     cam_capability_t *camera_cap = NULL;
   1873     mm_camera_lib_snapshot_params *dim = NULL;
   1874 
   1875     if ( NULL == handle ) {
   1876         LOGE(" Invalid handle");
   1877         rc = MM_CAMERA_E_INVALID_INPUT;
   1878         goto EXIT;
   1879     }
   1880 
   1881     camera_cap = (cam_capability_t *) handle->test_obj.cap_buf.mem_info.data;
   1882 
   1883     switch(cmd) {
   1884         case MM_CAMERA_LIB_FPS_RANGE:
   1885             if ( NULL != in_data ) {
   1886                 cam_fps_range_t range = *(( cam_fps_range_t * )in_data);
   1887                 rc = setFPSRange(&handle->test_obj, range);
   1888                 if (rc != MM_CAMERA_OK) {
   1889                         LOGE("setFPSRange() err=%d\n",
   1890                                     rc);
   1891                         goto EXIT;
   1892                 }
   1893             }
   1894             break;
   1895         case MM_CAMERA_LIB_FLASH:
   1896             if ( NULL != in_data ) {
   1897                 cam_flash_mode_t flash = *(( int * )in_data);
   1898                 rc = setFlash(&handle->test_obj, flash);
   1899                 if (rc != MM_CAMERA_OK) {
   1900                         LOGE("setFlash() err=%d\n",
   1901                                     rc);
   1902                         goto EXIT;
   1903                 }
   1904             }
   1905             break;
   1906         case MM_CAMERA_LIB_BESTSHOT:
   1907             if ( NULL != in_data ) {
   1908                 cam_scene_mode_type scene = *(( int * )in_data);
   1909                 rc = setScene(&handle->test_obj, scene);
   1910                 if (rc != MM_CAMERA_OK) {
   1911                         LOGE("setScene() err=%d\n",
   1912                                     rc);
   1913                         goto EXIT;
   1914                 }
   1915             }
   1916             break;
   1917         case MM_CAMERA_LIB_ZOOM:
   1918             if ( NULL != in_data ) {
   1919                 int zoom = *(( int * )in_data);
   1920                 rc = setZoom(&handle->test_obj, zoom);
   1921                 if (rc != MM_CAMERA_OK) {
   1922                         LOGE("setZoom() err=%d\n",
   1923                                     rc);
   1924                         goto EXIT;
   1925                 }
   1926             }
   1927             break;
   1928         case MM_CAMERA_LIB_ISO:
   1929             if ( NULL != in_data ) {
   1930                 cam_iso_mode_type iso = *(( int * )in_data);
   1931                 rc = setISO(&handle->test_obj, iso);
   1932                 if (rc != MM_CAMERA_OK) {
   1933                         LOGE("setISO() err=%d\n",
   1934                                     rc);
   1935                         goto EXIT;
   1936                 }
   1937             }
   1938             break;
   1939         case MM_CAMERA_LIB_SHARPNESS:
   1940             if ( NULL != in_data ) {
   1941                 int sharpness = *(( int * )in_data);
   1942                 rc = setSharpness(&handle->test_obj, sharpness);
   1943                 if (rc != MM_CAMERA_OK) {
   1944                         LOGE("setSharpness() err=%d\n",
   1945                                     rc);
   1946                         goto EXIT;
   1947                 }
   1948             }
   1949             break;
   1950         case MM_CAMERA_LIB_SATURATION:
   1951             if ( NULL != in_data ) {
   1952                 int saturation = *(( int * )in_data);
   1953                 rc = setSaturation(&handle->test_obj, saturation);
   1954                 if (rc != MM_CAMERA_OK) {
   1955                         LOGE("setSaturation() err=%d\n",
   1956                                     rc);
   1957                         goto EXIT;
   1958                 }
   1959             }
   1960             break;
   1961         case MM_CAMERA_LIB_CONTRAST:
   1962             if ( NULL != in_data ) {
   1963                 int contrast = *(( int * )in_data);
   1964                 rc = setContrast(&handle->test_obj, contrast);
   1965                 if (rc != MM_CAMERA_OK) {
   1966                         LOGE("setContrast() err=%d\n",
   1967                                     rc);
   1968                         goto EXIT;
   1969                 }
   1970             }
   1971             break;
   1972         case MM_CAMERA_LIB_SET_TINTLESS:
   1973             if ( NULL != in_data ) {
   1974                 int tintless = *(( int * )in_data);
   1975                 rc = setTintless(&handle->test_obj, tintless);
   1976                 if (rc != MM_CAMERA_OK) {
   1977                         LOGE("enlabe/disable:%d tintless() err=%d\n",
   1978                                     tintless, rc);
   1979                         goto EXIT;
   1980                 }
   1981             }
   1982             break;
   1983         case MM_CAMERA_LIB_BRIGHTNESS:
   1984             if ( NULL != in_data ) {
   1985                 int brightness = *(( int * )in_data);
   1986                 rc = setBrightness(&handle->test_obj, brightness);
   1987                 if (rc != MM_CAMERA_OK) {
   1988                         LOGE("setBrightness() err=%d\n",
   1989                                     rc);
   1990                         goto EXIT;
   1991                 }
   1992             }
   1993             break;
   1994         case MM_CAMERA_LIB_EXPOSURE_METERING:
   1995             if ( NULL != in_data ) {
   1996                 cam_auto_exposure_mode_type exp = *(( int * )in_data);
   1997                 rc = setExposureMetering(&handle->test_obj, exp);
   1998                 if (rc != MM_CAMERA_OK) {
   1999                         LOGE("setExposureMetering() err=%d\n",
   2000                                     rc);
   2001                         goto EXIT;
   2002                 }
   2003             }
   2004             break;
   2005         case MM_CAMERA_LIB_WB:
   2006             if ( NULL != in_data ) {
   2007                 cam_wb_mode_type wb = *(( int * )in_data);
   2008                 rc = setWhiteBalance(&handle->test_obj, wb);
   2009                 if (rc != MM_CAMERA_OK) {
   2010                         LOGE("setWhiteBalance() err=%d\n",
   2011                                     rc);
   2012                         goto EXIT;
   2013                 }
   2014             }
   2015             break;
   2016         case MM_CAMERA_LIB_ANTIBANDING:
   2017             if ( NULL != in_data ) {
   2018                 int antibanding = *(( int * )in_data);
   2019                 rc = setAntibanding(&handle->test_obj, antibanding);
   2020                 if (rc != MM_CAMERA_OK) {
   2021                         LOGE("setAntibanding() err=%d\n",
   2022                                     rc);
   2023                         goto EXIT;
   2024                 }
   2025             }
   2026             break;
   2027         case MM_CAMERA_LIB_EV:
   2028             if ( NULL != in_data ) {
   2029                 int ev = *(( int * )in_data);
   2030                 rc = setEVCompensation(&handle->test_obj, ev);
   2031                 if (rc != MM_CAMERA_OK) {
   2032                         LOGE("setEVCompensation() err=%d\n",
   2033                                     rc);
   2034                         goto EXIT;
   2035                 }
   2036             }
   2037             break;
   2038         case MM_CAMERA_LIB_ZSL_ENABLE:
   2039             if ( NULL != in_data) {
   2040                 int enable_zsl = *(( int * )in_data);
   2041                 if ( ( enable_zsl != handle->test_obj.zsl_enabled ) &&
   2042                         handle->stream_running ) {
   2043                     rc = mm_camera_lib_stop_stream(handle);
   2044                     if (rc != MM_CAMERA_OK) {
   2045                         LOGE("mm_camera_lib_stop_stream() err=%d\n",
   2046                                     rc);
   2047                         goto EXIT;
   2048                     }
   2049                     handle->test_obj.zsl_enabled = enable_zsl;
   2050                     rc = mm_camera_lib_start_stream(handle);
   2051                     if (rc != MM_CAMERA_OK) {
   2052                         LOGE("mm_camera_lib_start_stream() err=%d\n",
   2053                                     rc);
   2054                         goto EXIT;
   2055                     }
   2056                 } else {
   2057                     handle->test_obj.zsl_enabled = enable_zsl;
   2058                 }
   2059             }
   2060             break;
   2061         case MM_CAMERA_LIB_RAW_CAPTURE:
   2062 
   2063             if ( 0 == handle->stream_running ) {
   2064                 LOGE(" Streaming is not enabled!");
   2065                 rc = MM_CAMERA_E_INVALID_OPERATION;
   2066                 goto EXIT;
   2067             }
   2068 
   2069             rc = mm_camera_lib_stop_stream(handle);
   2070             if (rc != MM_CAMERA_OK) {
   2071                 LOGE("mm_camera_lib_stop_stream() err=%d\n",
   2072                             rc);
   2073                 goto EXIT;
   2074             }
   2075 
   2076             width = handle->test_obj.buffer_width;
   2077             height = handle->test_obj.buffer_height;
   2078             handle->test_obj.buffer_width =
   2079                     (uint32_t)camera_cap->raw_dim[0].width;
   2080             handle->test_obj.buffer_height =
   2081                     (uint32_t)camera_cap->raw_dim[0].height;
   2082             handle->test_obj.buffer_format = DEFAULT_RAW_FORMAT;
   2083             LOGE("MM_CAMERA_LIB_RAW_CAPTURE %dx%d\n",
   2084                     camera_cap->raw_dim[0].width,
   2085                     camera_cap->raw_dim[0].height);
   2086             rc = mm_app_start_capture_raw(&handle->test_obj, 1);
   2087             if (rc != MM_CAMERA_OK) {
   2088                 LOGE("mm_app_start_capture() err=%d\n",
   2089                             rc);
   2090                 goto EXIT;
   2091             }
   2092 
   2093             mm_camera_app_wait();
   2094 
   2095             rc = mm_app_stop_capture_raw(&handle->test_obj);
   2096             if (rc != MM_CAMERA_OK) {
   2097                 LOGE("mm_app_stop_capture() err=%d\n",
   2098                             rc);
   2099                 goto EXIT;
   2100             }
   2101 
   2102             handle->test_obj.buffer_width = width;
   2103             handle->test_obj.buffer_height = height;
   2104             handle->test_obj.buffer_format = DEFAULT_SNAPSHOT_FORMAT;
   2105             rc = mm_camera_lib_start_stream(handle);
   2106             if (rc != MM_CAMERA_OK) {
   2107                 LOGE("mm_camera_lib_start_stream() err=%d\n",
   2108                             rc);
   2109                 goto EXIT;
   2110             }
   2111 
   2112             break;
   2113 
   2114         case MM_CAMERA_LIB_JPEG_CAPTURE:
   2115             if ( 0 == handle->stream_running ) {
   2116                 LOGE(" Streaming is not enabled!");
   2117                 rc = MM_CAMERA_E_INVALID_OPERATION;
   2118                 goto EXIT;
   2119             }
   2120 
   2121             if ( NULL != in_data ) {
   2122                 dim = ( mm_camera_lib_snapshot_params * ) in_data;
   2123             }
   2124 
   2125             rc = tuneserver_capture(handle, dim);
   2126             if (rc != MM_CAMERA_OK) {
   2127                 LOGE("capture error %d\n",  rc);
   2128                 goto EXIT;
   2129             }
   2130             break;
   2131 
   2132         case MM_CAMERA_LIB_SET_FOCUS_MODE: {
   2133             cam_focus_mode_type mode = *((cam_focus_mode_type *)in_data);
   2134             handle->current_params.af_mode = mode;
   2135             rc = setFocusMode(&handle->test_obj, mode);
   2136             if (rc != MM_CAMERA_OK) {
   2137               LOGE("autofocus error\n");
   2138               goto EXIT;
   2139             }
   2140             break;
   2141         }
   2142 
   2143         case MM_CAMERA_LIB_DO_AF:
   2144             if (handle->test_obj.focus_supported) {
   2145               rc = handle->test_obj.cam->ops->do_auto_focus(handle->test_obj.cam->camera_handle);
   2146               if (rc != MM_CAMERA_OK) {
   2147                 LOGE("autofocus error\n");
   2148                 goto EXIT;
   2149               }
   2150               /*Waiting for Auto Focus Done Call Back*/
   2151               mm_camera_app_wait();
   2152             }
   2153             break;
   2154 
   2155         case MM_CAMERA_LIB_CANCEL_AF:
   2156             rc = handle->test_obj.cam->ops->cancel_auto_focus(handle->test_obj.cam->camera_handle);
   2157             if (rc != MM_CAMERA_OK) {
   2158                 LOGE("autofocus error\n");
   2159                 goto EXIT;
   2160             }
   2161 
   2162             break;
   2163 
   2164         case MM_CAMERA_LIB_LOCK_AWB:
   2165             rc = setAwbLock(&handle->test_obj, 1);
   2166             if (rc != MM_CAMERA_OK) {
   2167                 LOGE("AWB locking failed\n");
   2168                 goto EXIT;
   2169             }
   2170             break;
   2171 
   2172         case MM_CAMERA_LIB_UNLOCK_AWB:
   2173             rc = setAwbLock(&handle->test_obj, 0);
   2174             if (rc != MM_CAMERA_OK) {
   2175                 LOGE("AE unlocking failed\n");
   2176                 goto EXIT;
   2177             }
   2178             break;
   2179 
   2180         case MM_CAMERA_LIB_LOCK_AE:
   2181             rc = setAecLock(&handle->test_obj, 1);
   2182             if (rc != MM_CAMERA_OK) {
   2183                 LOGE("AE locking failed\n");
   2184                 goto EXIT;
   2185             }
   2186             break;
   2187 
   2188         case MM_CAMERA_LIB_UNLOCK_AE:
   2189             rc = setAecLock(&handle->test_obj, 0);
   2190             if (rc != MM_CAMERA_OK) {
   2191                 LOGE("AE unlocking failed\n");
   2192                 goto EXIT;
   2193             }
   2194             break;
   2195 
   2196        case MM_CAMERA_LIB_SET_3A_COMMAND: {
   2197           rc = set3Acommand(&handle->test_obj, (cam_eztune_cmd_data_t *)in_data);
   2198           if (rc != MM_CAMERA_OK) {
   2199             LOGE("3A set command error\n");
   2200             goto EXIT;
   2201           }
   2202           break;
   2203         }
   2204 
   2205        case MM_CAMERA_LIB_SET_AUTOFOCUS_TUNING: {
   2206            rc = setAutoFocusTuning(&handle->test_obj, in_data);
   2207            if (rc != MM_CAMERA_OK) {
   2208              LOGE("Set AF tuning failed\n");
   2209              goto EXIT;
   2210            }
   2211            break;
   2212        }
   2213 
   2214        case MM_CAMERA_LIB_SET_VFE_COMMAND: {
   2215            rc = setVfeCommand(&handle->test_obj, in_data);
   2216            if (rc != MM_CAMERA_OK) {
   2217              LOGE("Set vfe command failed\n");
   2218              goto EXIT;
   2219            }
   2220            break;
   2221        }
   2222 
   2223        case MM_CAMERA_LIB_SET_POSTPROC_COMMAND: {
   2224            rc = setPPCommand(&handle->test_obj, in_data);
   2225            if (rc != MM_CAMERA_OK) {
   2226              LOGE("Set pp command failed\n");
   2227              goto EXIT;
   2228            }
   2229            break;
   2230        }
   2231 
   2232         case MM_CAMERA_LIB_WNR_ENABLE: {
   2233             rc = setWNR(&handle->test_obj, *((uint8_t *)in_data));
   2234             if ( rc != MM_CAMERA_OK) {
   2235                 LOGE("Set wnr enable failed\n");
   2236                 goto EXIT;
   2237             }
   2238         }
   2239 
   2240       case MM_CAMERA_LIB_NO_ACTION:
   2241         default:
   2242             break;
   2243     };
   2244 
   2245 EXIT:
   2246 
   2247     return rc;
   2248 }
   2249 int mm_camera_lib_number_of_cameras(mm_camera_lib_handle *handle)
   2250 {
   2251     int rc = 0;
   2252 
   2253     if ( NULL == handle ) {
   2254         LOGE(" Invalid handle");
   2255         goto EXIT;
   2256     }
   2257 
   2258     rc = handle->app_ctx.num_cameras;
   2259 
   2260 EXIT:
   2261 
   2262     return rc;
   2263 }
   2264 
   2265 int mm_camera_lib_close(mm_camera_lib_handle *handle)
   2266 {
   2267     int rc = MM_CAMERA_OK;
   2268 
   2269     if ( NULL == handle ) {
   2270         LOGE(" Invalid handle");
   2271         rc = MM_CAMERA_E_INVALID_INPUT;
   2272         goto EXIT;
   2273     }
   2274 
   2275     //rc = mm_app_close_fb(&handle->test_obj);
   2276     rc = MM_CAMERA_OK;
   2277     if (rc != MM_CAMERA_OK) {
   2278         LOGE("mm_app_close_fb() err=%d\n",
   2279                     rc);
   2280         goto EXIT;
   2281     }
   2282 
   2283     rc = mm_app_close(&handle->test_obj);
   2284     if (rc != MM_CAMERA_OK) {
   2285         LOGE("mm_app_close() err=%d\n",
   2286                     rc);
   2287         goto EXIT;
   2288     }
   2289 
   2290 EXIT:
   2291     return rc;
   2292 }
   2293 
   2294 int mm_camera_lib_set_preview_usercb(
   2295    mm_camera_lib_handle *handle, cam_stream_user_cb cb)
   2296 {
   2297     if (handle->test_obj.user_preview_cb != NULL) {
   2298         LOGE(" already set preview callbacks\n");
   2299         return -1;
   2300     }
   2301     handle->test_obj.user_preview_cb = *cb;
   2302     return 0;
   2303 }
   2304 
   2305 int mm_app_set_preview_fps_range(mm_camera_test_obj_t *test_obj,
   2306                         cam_fps_range_t *fpsRange)
   2307 {
   2308     int rc = MM_CAMERA_OK;
   2309     LOGH("preview fps range: min=%f, max=%f.",
   2310             fpsRange->min_fps, fpsRange->max_fps);
   2311     rc = setFPSRange(test_obj, *fpsRange);
   2312 
   2313     if (rc != MM_CAMERA_OK) {
   2314         LOGE("add_parm_entry_tobatch failed !!");
   2315         return rc;
   2316     }
   2317 
   2318     return rc;
   2319 }
   2320 
   2321 int mm_app_set_face_detection(mm_camera_test_obj_t *test_obj,
   2322         cam_fd_set_parm_t *fd_set_parm)
   2323 {
   2324     int rc = MM_CAMERA_OK;
   2325 
   2326     if (test_obj == NULL || fd_set_parm == NULL) {
   2327         LOGE(" invalid params!");
   2328         return MM_CAMERA_E_INVALID_INPUT;
   2329     }
   2330 
   2331     LOGH("mode = %d, num_fd = %d",
   2332           fd_set_parm->fd_mode, fd_set_parm->num_fd);
   2333 
   2334     rc = initBatchUpdate(test_obj);
   2335     if (rc != MM_CAMERA_OK) {
   2336         LOGE("Batch camera parameter update failed\n");
   2337         goto ERROR;
   2338     }
   2339 
   2340     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   2341         CAM_INTF_PARM_FD, *fd_set_parm)) {
   2342         LOGE("FD parameter not added to batch\n");
   2343         rc = -1;
   2344         goto ERROR;
   2345     }
   2346 
   2347     rc = commitSetBatch(test_obj);
   2348     if (rc != MM_CAMERA_OK) {
   2349         LOGE("Batch parameters commit failed\n");
   2350         goto ERROR;
   2351     }
   2352 
   2353 ERROR:
   2354     return rc;
   2355 }
   2356 
   2357 int mm_app_set_flash_mode(mm_camera_test_obj_t *test_obj,
   2358         cam_flash_mode_t flashMode)
   2359 {
   2360     int rc = MM_CAMERA_OK;
   2361 
   2362     if (test_obj == NULL) {
   2363         LOGE(" invalid params!");
   2364         return MM_CAMERA_E_INVALID_INPUT;
   2365     }
   2366 
   2367     LOGH("mode = %d",  (int)flashMode);
   2368 
   2369     rc = initBatchUpdate(test_obj);
   2370     if (rc != MM_CAMERA_OK) {
   2371         LOGE("Batch camera parameter update failed\n");
   2372         goto ERROR;
   2373     }
   2374 
   2375     if (ADD_SET_PARAM_ENTRY_TO_BATCH(test_obj->parm_buf.mem_info.data,
   2376         CAM_INTF_PARM_LED_MODE, flashMode)) {
   2377         LOGE("Flash mode parameter not added to batch\n");
   2378         rc = -1;
   2379         goto ERROR;
   2380     }
   2381 
   2382     rc = commitSetBatch(test_obj);
   2383     if (rc != MM_CAMERA_OK) {
   2384         LOGE("Batch parameters commit failed\n");
   2385         goto ERROR;
   2386     }
   2387 
   2388 ERROR:
   2389     return rc;
   2390 }
   2391 
   2392 int mm_app_set_metadata_usercb(mm_camera_test_obj_t *test_obj,
   2393                         cam_stream_user_cb usercb)
   2394 {
   2395     if (test_obj == NULL || usercb == NULL) {
   2396         LOGE(" invalid params!");
   2397         return MM_CAMERA_E_INVALID_INPUT;
   2398     }
   2399 
   2400     LOGH("%s, set user metadata callback, addr: %p\n",  usercb);
   2401 
   2402     if (test_obj->user_metadata_cb != NULL) {
   2403         LOGH("%s, already set user metadata callback");
   2404     }
   2405     test_obj->user_metadata_cb = usercb;
   2406 
   2407     return 0;
   2408 }
   2409 
   2410 
   2411