Camera3: Fix JPEG Exif CTS test

1) Destroy an old jpeg session before creating a new one
2) Fix error handling from mm-jpeg-interface to HAL
3) Fix the way GPS_PROCESSING_METHOD is read and updated in HAL

Change-Id: I6e784bc53fb1cdc1110d1b0ecfc0b1da435dbd14
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/camera/QCamera2/HAL3/QCamera3Channel.cpp b/camera/QCamera2/HAL3/QCamera3Channel.cpp
index 4e6de92..b9bc65d 100644
--- a/camera/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/camera/QCamera2/HAL3/QCamera3Channel.cpp
@@ -1297,15 +1297,13 @@
  *              none-zero failure code
  *==========================================================================*/
 int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
-                                                      uint32_t &count, int value)
+                                   uint32_t &count, char* value)
 {
-    char str[30];
-    snprintf(str, sizeof(str), "%d", value);
-    if(str != NULL) {
+    if(value != NULL) {
         memcpy(gpsProcessingMethod, ExifAsciiPrefix, EXIF_ASCII_PREFIX_SIZE);
         count = EXIF_ASCII_PREFIX_SIZE;
-        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, str, strlen(str));
-        count += strlen(str);
+        strncpy(gpsProcessingMethod + EXIF_ASCII_PREFIX_SIZE, value, strlen(value));
+        count += strlen(value);
         gpsProcessingMethod[count++] = '\0'; // increase 1 for the last NULL char
         return NO_ERROR;
     } else {
@@ -1508,83 +1506,94 @@
                    1,
                    (void *)&(isoSpeed));
 
-    char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
-    count = 0;
-    rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method);
-    if(rc == NO_ERROR) {
-        exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
-                       EXIF_ASCII,
-                       count,
-                       (void *)gpsProcessingMethod);
-    } else {
-        ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
+
+    if (strlen(mJpegSettings->gps_processing_method) > 0) {
+        char gpsProcessingMethod[EXIF_ASCII_PREFIX_SIZE + GPS_PROCESSING_METHOD_SIZE];
+        count = 0;
+        rc = getExifGpsProcessingMethod(gpsProcessingMethod, count, mJpegSettings->gps_processing_method);
+        if(rc == NO_ERROR) {
+            exif->addEntry(EXIFTAGID_GPS_PROCESSINGMETHOD,
+                           EXIF_ASCII,
+                           count,
+                           (void *)gpsProcessingMethod);
+        } else {
+            ALOGE("%s: getExifGpsProcessingMethod failed", __func__);
+        }
     }
 
-    rat_t latitude[3];
-    char latRef[2];
-    rc = getExifLatitude(latitude, latRef, mJpegSettings->gps_coordinates[0]);
-    if(rc == NO_ERROR) {
-        exif->addEntry(EXIFTAGID_GPS_LATITUDE,
-                       EXIF_RATIONAL,
-                       3,
-                       (void *)latitude);
-        exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
-                       EXIF_ASCII,
-                       2,
-                       (void *)latRef);
-    } else {
-        ALOGE("%s: getExifLatitude failed", __func__);
+    if (mJpegSettings->gps_coordinates[0]) {
+        rat_t latitude[3];
+        char latRef[2];
+        rc = getExifLatitude(latitude, latRef, *(mJpegSettings->gps_coordinates[0]));
+        if(rc == NO_ERROR) {
+            exif->addEntry(EXIFTAGID_GPS_LATITUDE,
+                           EXIF_RATIONAL,
+                           3,
+                           (void *)latitude);
+            exif->addEntry(EXIFTAGID_GPS_LATITUDE_REF,
+                           EXIF_ASCII,
+                           2,
+                           (void *)latRef);
+        } else {
+            ALOGE("%s: getExifLatitude failed", __func__);
+        }
     }
 
-    rat_t longitude[3];
-    char lonRef[2];
-    rc = getExifLongitude(longitude, lonRef, mJpegSettings->gps_coordinates[1]);
-    if(rc == NO_ERROR) {
-        exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
-                       EXIF_RATIONAL,
-                       3,
-                       (void *)longitude);
+    if (mJpegSettings->gps_coordinates[1]) {
+        rat_t longitude[3];
+        char lonRef[2];
+        rc = getExifLongitude(longitude, lonRef, *(mJpegSettings->gps_coordinates[1]));
+        if(rc == NO_ERROR) {
+            exif->addEntry(EXIFTAGID_GPS_LONGITUDE,
+                           EXIF_RATIONAL,
+                           3,
+                           (void *)longitude);
 
-        exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
-                       EXIF_ASCII,
-                       2,
-                       (void *)lonRef);
-    } else {
-        ALOGE("%s: getExifLongitude failed", __func__);
+            exif->addEntry(EXIFTAGID_GPS_LONGITUDE_REF,
+                           EXIF_ASCII,
+                           2,
+                           (void *)lonRef);
+        } else {
+            ALOGE("%s: getExifLongitude failed", __func__);
+        }
     }
 
-    rat_t altitude;
-    char altRef;
-    rc = getExifAltitude(&altitude, &altRef, mJpegSettings->gps_coordinates[2]);
-    if(rc == NO_ERROR) {
-        exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
-                       EXIF_RATIONAL,
-                       1,
-                       (void *)&(altitude));
+    if (mJpegSettings->gps_coordinates[2]) {
+        rat_t altitude;
+        char altRef;
+        rc = getExifAltitude(&altitude, &altRef, *(mJpegSettings->gps_coordinates[2]));
+        if(rc == NO_ERROR) {
+            exif->addEntry(EXIFTAGID_GPS_ALTITUDE,
+                           EXIF_RATIONAL,
+                           1,
+                           (void *)&(altitude));
 
-        exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
-                       EXIF_BYTE,
-                       1,
-                       (void *)&altRef);
-    } else {
-        ALOGE("%s: getExifAltitude failed", __func__);
+            exif->addEntry(EXIFTAGID_GPS_ALTITUDE_REF,
+                           EXIF_BYTE,
+                           1,
+                           (void *)&altRef);
+        } else {
+            ALOGE("%s: getExifAltitude failed", __func__);
+        }
     }
 
-    char gpsDateStamp[20];
-    rat_t gpsTimeStamp[3];
-    rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, mJpegSettings->gps_timestamp);
-    if(rc == NO_ERROR) {
-        exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
-                       EXIF_ASCII,
-                       strlen(gpsDateStamp) + 1,
-                       (void *)gpsDateStamp);
+    if (mJpegSettings->gps_timestamp) {
+        char gpsDateStamp[20];
+        rat_t gpsTimeStamp[3];
+        rc = getExifGpsDateTimeStamp(gpsDateStamp, 20, gpsTimeStamp, *(mJpegSettings->gps_timestamp));
+        if(rc == NO_ERROR) {
+            exif->addEntry(EXIFTAGID_GPS_DATESTAMP,
+                           EXIF_ASCII,
+                           strlen(gpsDateStamp) + 1,
+                           (void *)gpsDateStamp);
 
-        exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
-                       EXIF_RATIONAL,
-                       3,
-                       (void *)gpsTimeStamp);
-    } else {
-        ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
+            exif->addEntry(EXIFTAGID_GPS_TIMESTAMP,
+                           EXIF_RATIONAL,
+                           3,
+                           (void *)gpsTimeStamp);
+        } else {
+            ALOGE("%s: getExifGpsDataTimeStamp failed", __func__);
+        }
     }
 
     srat_t exposure_val;
diff --git a/camera/QCamera2/HAL3/QCamera3HALHeader.h b/camera/QCamera2/HAL3/QCamera3HALHeader.h
index 72fd003..867a41d 100644
--- a/camera/QCamera2/HAL3/QCamera3HALHeader.h
+++ b/camera/QCamera2/HAL3/QCamera3HALHeader.h
@@ -47,14 +47,14 @@
         int32_t jpeg_orientation;
         uint8_t jpeg_quality;
         cam_dimension_t thumbnail_size;
-        int64_t gps_timestamp;
-        double gps_coordinates[3];
-        uint8_t gps_processing_method;
         int32_t sensor_sensitivity;
         float lens_focal_length;
         int32_t max_jpeg_size;
         int exposure_compensation;
         cam_rational_type_t exposure_comp_step;
+        int64_t* gps_timestamp;
+        double* gps_coordinates[3];
+        char gps_processing_method[35];
     } jpeg_settings_t;
 
     typedef struct {
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 5ebf238..db34c3c 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -2352,10 +2352,8 @@
                         gCamCapability[mCameraId]->filter_densities_count);
     }
 
-    if (gCamCapability[mCameraId]->focal_lengths_count) {
-        float default_focal_length = gCamCapability[mCameraId]->focal_length;
-        settings.update(ANDROID_LENS_FOCAL_LENGTH, &default_focal_length, 1);
-    }
+    float default_focal_length = gCamCapability[mCameraId]->focal_length;
+    settings.update(ANDROID_LENS_FOCAL_LENGTH, &default_focal_length, 1);
 
     mDefaultMetadata[type] = settings.release();
 
@@ -2841,6 +2839,16 @@
                                   (const camera_metadata_t *settings)
 {
     if (mJpegSettings) {
+        if (mJpegSettings->gps_timestamp) {
+            free(mJpegSettings->gps_timestamp);
+            mJpegSettings->gps_timestamp = NULL;
+        }
+        if (mJpegSettings->gps_coordinates) {
+            for (int i = 0; i < 3; i++) {
+                free(mJpegSettings->gps_coordinates[i]);
+                mJpegSettings->gps_coordinates[i] = NULL;
+            }
+        }
         free(mJpegSettings);
         mJpegSettings = NULL;
     }
@@ -2871,26 +2879,35 @@
     }
     if (jpeg_settings.exists(ANDROID_JPEG_GPS_COORDINATES)) {
         for (int i = 0; i < 3; i++) {
-            mJpegSettings->gps_coordinates[i] =
+            mJpegSettings->gps_coordinates[i] = (double*)malloc(sizeof(double*));
+            *(mJpegSettings->gps_coordinates[i]) =
                 jpeg_settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[i];
         }
     } else{
-        for (int i = 0; i < 3; i++) {
-            mJpegSettings->gps_coordinates[i] = 0;
+       for (int i = 0; i < 3; i++) {
+            mJpegSettings->gps_coordinates[i] = NULL;
         }
     }
+
     if (jpeg_settings.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
-        mJpegSettings->gps_timestamp =
+        mJpegSettings->gps_timestamp = (int64_t*)malloc(sizeof(int64_t*));
+        *(mJpegSettings->gps_timestamp) =
             jpeg_settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64[0];
-    } else{
-        mJpegSettings->gps_timestamp = 0;
+    } else {
+        mJpegSettings->gps_timestamp = NULL;
     }
 
     if (jpeg_settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
-        mJpegSettings->gps_processing_method =
-            jpeg_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8[0];
-    } else{
-        mJpegSettings->gps_processing_method = 0;
+        int len = jpeg_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).count;
+        for (int i = 0; i < len; i++) {
+            mJpegSettings->gps_processing_method[i] =
+                jpeg_settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8[i];
+        }
+        if (mJpegSettings->gps_processing_method[len-1] != '\0') {
+            mJpegSettings->gps_processing_method[len] = '\0';
+        }
+    } else {
+        mJpegSettings->gps_processing_method[0] = '\0';
     }
 
     if (jpeg_settings.exists(ANDROID_SENSOR_SENSITIVITY)) {
@@ -2899,6 +2916,7 @@
     } else {
         mJpegSettings->sensor_sensitivity = mMetadataResponse.iso_speed;
     }
+
     if (jpeg_settings.exists(ANDROID_LENS_FOCAL_LENGTH)) {
         mJpegSettings->lens_focal_length =
             jpeg_settings.find(ANDROID_LENS_FOCAL_LENGTH).data.f[0];
diff --git a/camera/QCamera2/HAL3/QCamera3PostProc.cpp b/camera/QCamera2/HAL3/QCamera3PostProc.cpp
index b211644..632c686 100644
--- a/camera/QCamera2/HAL3/QCamera3PostProc.cpp
+++ b/camera/QCamera2/HAL3/QCamera3PostProc.cpp
@@ -694,6 +694,16 @@
 
     ALOGD("%s: Need new session?:%d",__func__, needNewSess);
     if (needNewSess) {
+        //creating a new session, so we must destroy the old one
+        if ( 0 < mJpegSessionId ) {
+            ret = mJpegHandle.destroy_session(mJpegSessionId);
+            if (ret != NO_ERROR) {
+                ALOGE("%s: Error destroying an old jpeg encoding session, id = %d",
+                      __func__, mJpegSessionId);
+                return ret;
+            }
+            mJpegSessionId = 0;
+        }
         // create jpeg encoding session
         mm_jpeg_encode_params_t encodeParam;
         memset(&encodeParam, 0, sizeof(mm_jpeg_encode_params_t));
@@ -703,7 +713,7 @@
                      encodeParam.num_src_bufs,encodeParam.num_tmb_bufs,encodeParam.num_dst_bufs);
         ret = mJpegHandle.create_session(mJpegClientHandle, &encodeParam, &mJpegSessionId);
         if (ret != NO_ERROR) {
-            ALOGE("%s: error creating a new jpeg encoding session", __func__);
+            ALOGE("%s: Error creating a new jpeg encoding session, ret = %d", __func__, ret);
             return ret;
         }
         needNewSess = FALSE;
diff --git a/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c b/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
index 013d864..79fefc1 100644
--- a/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
+++ b/camera/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
@@ -1930,27 +1930,27 @@
   if ((p_params->num_src_bufs > MM_JPEG_MAX_BUF)
     || (p_params->num_dst_bufs > MM_JPEG_MAX_BUF)) {
     CDBG_ERROR("%s:%d] invalid num buffers", __func__, __LINE__);
-    return rc;
+    return -1;
   }
 
   /* check if valid client */
   clnt_idx = mm_jpeg_util_get_index_by_handler(client_hdl);
   if (clnt_idx >= MAX_JPEG_CLIENT_NUM) {
     CDBG_ERROR("%s: invalid client with handler (%d)", __func__, client_hdl);
-    return rc;
+    return -1;
   }
 
   session_idx = mm_jpeg_get_new_session_idx(my_obj, clnt_idx, &p_session);
   if (session_idx < 0) {
     CDBG_ERROR("%s:%d] invalid session id (%d)", __func__, __LINE__, session_idx);
-    return rc;
+    return -1;
   }
 
   ret = mm_jpeg_session_create(p_session);
   if (OMX_ErrorNone != ret) {
     p_session->active = OMX_FALSE;
     CDBG_ERROR("%s:%d] jpeg session create failed", __func__, __LINE__);
-    return rc;
+    return ret;
   }
 
   *p_session_id = (JOB_ID_MAGICVAL << 24) | (session_idx << 8) | clnt_idx;
@@ -1962,7 +1962,7 @@
   p_session->jpeg_obj = (void*)my_obj; /* save a ptr to jpeg_obj */
   CDBG("%s:%d] session id %x", __func__, __LINE__, *p_session_id);
 
-  return rc;
+  return ret;
 }
 
 /** mm_jpeg_destroy_session: