Camera2: Use scene mode override parameter

- Read in SCENE_MODE_OVERRIDES static parameter if available.
  Use it to select AF/AE/AWB modes when a scene mode is set.
- Add quirks structure to parameters; not yet used
- Fix desynchronization between range and single FPS value.
  Still need to sort out best way to convert from one to another.

Bug: 7259959
Bug: 7159577
Bug: 7172543

Change-Id: I0d07c31d5f21fbc4b0ec2fa23f7f778073d2d6e0
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 33e0b56..1c650f6 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -913,6 +913,7 @@
 status_t Camera2Client::autoFocus() {
     ATRACE_CALL();
     Mutex::Autolock icl(mICameraLock);
+    ALOGV("%s: Camera %d", __FUNCTION__, mCameraId);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
@@ -931,6 +932,7 @@
 status_t Camera2Client::cancelAutoFocus() {
     ATRACE_CALL();
     Mutex::Autolock icl(mICameraLock);
+    ALOGV("%s: Camera %d", __FUNCTION__, mCameraId);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
 
@@ -1000,7 +1002,7 @@
 
 status_t Camera2Client::setParameters(const String8& params) {
     ATRACE_CALL();
-    ALOGV("%s: E", __FUNCTION__);
+    ALOGV("%s: Camera %d", __FUNCTION__, mCameraId);
     Mutex::Autolock icl(mICameraLock);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
@@ -1017,13 +1019,13 @@
 
 String8 Camera2Client::getParameters() const {
     ATRACE_CALL();
+    ALOGV("%s: Camera %d", __FUNCTION__, mCameraId);
     Mutex::Autolock icl(mICameraLock);
     if ( checkPid(__FUNCTION__) != OK) return String8();
 
     SharedParameters::ReadLock l(mParameters);
 
-    // TODO: Deal with focus distances
-    return l.mParameters.paramsFlattened;
+    return l.mParameters.get();
 }
 
 status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
diff --git a/services/camera/libcameraservice/camera2/BurstCapture.cpp b/services/camera/libcameraservice/camera2/BurstCapture.cpp
index f4a2aa1..f56c50c 100644
--- a/services/camera/libcameraservice/camera2/BurstCapture.cpp
+++ b/services/camera/libcameraservice/camera2/BurstCapture.cpp
@@ -22,8 +22,8 @@
 
 #include "BurstCapture.h"
 
-#include "JpegCompressor.h"
 #include "../Camera2Client.h"
+#include "JpegCompressor.h"
 
 namespace android {
 namespace camera2 {
diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp
index 8ae390d..fd44a3e 100644
--- a/services/camera/libcameraservice/camera2/Parameters.cpp
+++ b/services/camera/libcameraservice/camera2/Parameters.cpp
@@ -27,7 +27,6 @@
 
 #include "Parameters.h"
 #include "system/camera.h"
-#include "camera/CameraParameters.h"
 
 namespace android {
 namespace camera2 {
@@ -54,8 +53,6 @@
     res = buildFastInfo();
     if (res != OK) return res;
 
-    CameraParameters params;
-
     camera_metadata_ro_entry_t availableProcessedSizes =
         staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
     if (!availableProcessedSizes.count) return NO_INIT;
@@ -171,6 +168,7 @@
     // still have to do something sane for them
 
     // NOTE: Not scaled like FPS range values are.
+    previewFps = previewFpsRange[0];
     params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
             previewFpsRange[0]);
 
@@ -414,7 +412,7 @@
                 supportedAntibanding);
     }
 
-    sceneMode = ANDROID_CONTROL_OFF;
+    sceneMode = ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
     params.set(CameraParameters::KEY_SCENE_MODE,
             CameraParameters::SCENE_MODE_AUTO);
 
@@ -768,6 +766,10 @@
     return OK;
 }
 
+String8 Parameters::get() const {
+    return paramsFlattened;
+}
+
 status_t Parameters::buildFastInfo() {
 
     camera_metadata_ro_entry_t activeArraySize =
@@ -811,6 +813,77 @@
 
     int32_t maxFaces = maxFacesDetected.data.i32[0];
 
+    camera_metadata_ro_entry_t availableSceneModes =
+        staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+    camera_metadata_ro_entry_t sceneModeOverrides =
+        staticInfo(ANDROID_CONTROL_SCENE_MODE_OVERRIDES);
+    camera_metadata_ro_entry_t minFocusDistance =
+        staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
+    bool fixedLens = (minFocusDistance.data.f[0] == 0);
+
+    if (sceneModeOverrides.count > 0) {
+        // sceneModeOverrides is defined to have 3 entries for each scene mode,
+        // which are AE, AWB, and AF override modes the HAL wants for that scene
+        // mode.
+        const size_t kModesPerSceneMode = 3;
+        if (sceneModeOverrides.count !=
+                availableSceneModes.count * kModesPerSceneMode) {
+            ALOGE("%s: Camera %d: Scene mode override list is an "
+                    "unexpected size: %d (expected %d)", __FUNCTION__,
+                    cameraId, sceneModeOverrides.count,
+                    availableSceneModes.count);
+            return NO_INIT;
+        }
+        for (size_t i = 0; i < availableSceneModes.count; i++) {
+            DeviceInfo::OverrideModes modes;
+            uint8_t aeMode =
+                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 0];
+            switch(aeMode) {
+                case ANDROID_CONTROL_AE_ON:
+                    modes.flashMode = FLASH_MODE_OFF;
+                    break;
+                case ANDROID_CONTROL_AE_ON_AUTO_FLASH:
+                    modes.flashMode = FLASH_MODE_AUTO;
+                    break;
+                case ANDROID_CONTROL_AE_ON_ALWAYS_FLASH:
+                    modes.flashMode = FLASH_MODE_ON;
+                    break;
+                case ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE:
+                    modes.flashMode = FLASH_MODE_RED_EYE;
+                    break;
+                default:
+                    ALOGE("%s: Unknown override AE mode: %d", __FUNCTION__,
+                            aeMode);
+                    modes.flashMode = FLASH_MODE_INVALID;
+                    break;
+            }
+            modes.wbMode =
+                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 1];
+            uint8_t afMode =
+                    sceneModeOverrides.data.u8[i * kModesPerSceneMode + 2];
+            switch(afMode) {
+                case ANDROID_CONTROL_AF_OFF:
+                    modes.focusMode = fixedLens ?
+                            FOCUS_MODE_FIXED : FOCUS_MODE_INFINITY;
+                    break;
+                case ANDROID_CONTROL_AF_AUTO:
+                case ANDROID_CONTROL_AF_MACRO:
+                case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
+                case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
+                case ANDROID_CONTROL_AF_EDOF:
+                    modes.focusMode = static_cast<focusMode_t>(afMode);
+                    break;
+                default:
+                    ALOGE("%s: Unknown override AF mode: %d", __FUNCTION__,
+                            afMode);
+                    modes.focusMode = FOCUS_MODE_INVALID;
+                    break;
+            }
+            fastInfo.sceneModeOverrides.add(availableSceneModes.data.u8[i],
+                    modes);
+        }
+    }
+
     fastInfo.arrayWidth = arrayWidth;
     fastInfo.arrayHeight = arrayHeight;
     fastInfo.bestFaceDetectMode = bestFaceDetectMode;
@@ -846,10 +919,10 @@
     return entry;
 }
 
-status_t Parameters::set(const String8& params) {
+status_t Parameters::set(const String8& paramString) {
     status_t res;
 
-    CameraParameters newParams(params);
+    CameraParameters newParams(paramString);
 
     // TODO: Currently ignoring any changes to supposedly read-only parameters
     // such as supported preview sizes, etc. Should probably produce an error if
@@ -918,6 +991,7 @@
             return BAD_VALUE;
         }
         validatedParams.previewFps = validatedParams.previewFpsRange[0];
+        newParams.setPreviewFrameRate(validatedParams.previewFps);
     }
 
     // PREVIEW_FORMAT
@@ -1096,23 +1170,6 @@
         validatedParams.gpsEnabled = false;
     }
 
-    // WHITE_BALANCE
-    validatedParams.wbMode = wbModeStringToEnum(
-        newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
-    if (validatedParams.wbMode != wbMode) {
-        camera_metadata_ro_entry_t availableWbModes =
-            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
-        for (i = 0; i < availableWbModes.count; i++) {
-            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
-        }
-        if (i == availableWbModes.count) {
-            ALOGE("%s: Requested white balance mode %s is not supported",
-                    __FUNCTION__,
-                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
-            return BAD_VALUE;
-        }
-    }
-
     // EFFECT
     validatedParams.effectMode = effectModeStringToEnum(
         newParams.get(CameraParameters::KEY_EFFECT) );
@@ -1167,10 +1224,22 @@
             return BAD_VALUE;
         }
     }
+    bool sceneModeSet =
+            validatedParams.sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
 
     // FLASH_MODE
-    validatedParams.flashMode = flashModeStringToEnum(
-        newParams.get(CameraParameters::KEY_FLASH_MODE) );
+    if (sceneModeSet) {
+        validatedParams.flashMode =
+                fastInfo.sceneModeOverrides.
+                        valueFor(validatedParams.sceneMode).flashMode;
+    } else {
+        validatedParams.flashMode = FLASH_MODE_INVALID;
+    }
+    if (validatedParams.flashMode == FLASH_MODE_INVALID) {
+        validatedParams.flashMode = flashModeStringToEnum(
+            newParams.get(CameraParameters::KEY_FLASH_MODE) );
+    }
+
     if (validatedParams.flashMode != flashMode) {
         camera_metadata_ro_entry_t flashAvailable =
             staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
@@ -1199,11 +1268,52 @@
                     newParams.get(CameraParameters::KEY_FLASH_MODE));
             return BAD_VALUE;
         }
+        // Update in case of override
+        newParams.set(CameraParameters::KEY_FLASH_MODE,
+                flashModeEnumToString(validatedParams.flashMode));
+    }
+
+    // WHITE_BALANCE
+    if (sceneModeSet) {
+        validatedParams.wbMode =
+                fastInfo.sceneModeOverrides.
+                        valueFor(validatedParams.sceneMode).wbMode;
+    } else {
+        validatedParams.wbMode = ANDROID_CONTROL_AWB_OFF;
+    }
+    if (validatedParams.wbMode == ANDROID_CONTROL_AWB_OFF) {
+        validatedParams.wbMode = wbModeStringToEnum(
+            newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
+    }
+    if (validatedParams.wbMode != wbMode) {
+        camera_metadata_ro_entry_t availableWbModes =
+            staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
+        for (i = 0; i < availableWbModes.count; i++) {
+            if (validatedParams.wbMode == availableWbModes.data.u8[i]) break;
+        }
+        if (i == availableWbModes.count) {
+            ALOGE("%s: Requested white balance mode %s is not supported",
+                    __FUNCTION__,
+                    newParams.get(CameraParameters::KEY_WHITE_BALANCE));
+            return BAD_VALUE;
+        }
+        // Update in case of override
+        newParams.set(CameraParameters::KEY_WHITE_BALANCE,
+                wbModeEnumToString(validatedParams.wbMode));
     }
 
     // FOCUS_MODE
-    validatedParams.focusMode = focusModeStringToEnum(
-        newParams.get(CameraParameters::KEY_FOCUS_MODE));
+    if (sceneModeSet) {
+        validatedParams.focusMode =
+                fastInfo.sceneModeOverrides.
+                        valueFor(validatedParams.sceneMode).focusMode;
+    } else {
+        validatedParams.focusMode = FOCUS_MODE_INVALID;
+    }
+    if (validatedParams.focusMode == FOCUS_MODE_INVALID) {
+        validatedParams.focusMode = focusModeStringToEnum(
+                newParams.get(CameraParameters::KEY_FOCUS_MODE) );
+    }
     if (validatedParams.focusMode != focusMode) {
         validatedParams.currentAfTriggerId = -1;
         if (validatedParams.focusMode != Parameters::FOCUS_MODE_FIXED) {
@@ -1231,6 +1341,9 @@
                 }
             }
         }
+        // Update in case of override
+        newParams.set(CameraParameters::KEY_FOCUS_MODE,
+                focusModeEnumToString(validatedParams.focusMode));
     } else {
         validatedParams.currentAfTriggerId = currentAfTriggerId;
     }
@@ -1333,9 +1446,12 @@
 
     /** Update internal parameters */
 
-    validatedParams.paramsFlattened = params;
     *this = validatedParams;
 
+    // Need to flatten again in case of overrides
+    paramsFlattened = newParams.flatten();
+    params = newParams;
+
     return OK;
 }
 
@@ -1352,10 +1468,6 @@
             previewFpsRange, 2);
     if (res != OK) return res;
 
-    res = request->update(ANDROID_CONTROL_AWB_MODE,
-            &wbMode, 1);
-    if (res != OK) return res;
-
     uint8_t reqWbLock = autoWhiteBalanceLock ?
             ANDROID_CONTROL_AWB_LOCK_ON : ANDROID_CONTROL_AWB_LOCK_OFF;
     res = request->update(ANDROID_CONTROL_AWB_LOCK,
@@ -1372,8 +1484,10 @@
     // camera is in a face-priority mode. HAL2 splits this into separate parts
     // (face detection statistics and face priority scene mode). Map from other
     // to the other.
+    bool sceneModeActive =
+            sceneMode != (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
     uint8_t reqControlMode = ANDROID_CONTROL_AUTO;
-    if (enableFaceDetect || sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
+    if (enableFaceDetect || sceneModeActive) {
         reqControlMode = ANDROID_CONTROL_USE_SCENE_MODE;
     }
     res = request->update(ANDROID_CONTROL_MODE,
@@ -1381,8 +1495,7 @@
     if (res != OK) return res;
 
     uint8_t reqSceneMode =
-            (sceneMode !=
-                    (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ? sceneMode :
+            sceneModeActive ? sceneMode :
             enableFaceDetect ? (uint8_t)ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY :
             (uint8_t)ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED;
     res = request->update(ANDROID_CONTROL_SCENE_MODE,
@@ -1390,7 +1503,7 @@
     if (res != OK) return res;
 
     uint8_t reqFlashMode = ANDROID_FLASH_OFF;
-    uint8_t reqAeMode;
+    uint8_t reqAeMode = ANDROID_CONTROL_AE_OFF;
     switch (flashMode) {
         case Parameters::FLASH_MODE_OFF:
             reqAeMode = ANDROID_CONTROL_AE_ON; break;
@@ -1407,7 +1520,7 @@
         default:
             ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
                     cameraId, flashMode);
-            return BAD_VALUE;
+                return BAD_VALUE;
     }
     res = request->update(ANDROID_FLASH_MODE,
             &reqFlashMode, 1);
@@ -1420,9 +1533,14 @@
             ANDROID_CONTROL_AE_LOCK_ON : ANDROID_CONTROL_AE_LOCK_OFF;
     res = request->update(ANDROID_CONTROL_AE_LOCK,
             &reqAeLock, 1);
+    if (res != OK) return res;
+
+    res = request->update(ANDROID_CONTROL_AWB_MODE,
+            &wbMode, 1);
+    if (res != OK) return res;
 
     float reqFocusDistance = 0; // infinity focus in diopters
-    uint8_t reqFocusMode;
+    uint8_t reqFocusMode = ANDROID_CONTROL_AF_OFF;
     switch (focusMode) {
         case Parameters::FOCUS_MODE_AUTO:
         case Parameters::FOCUS_MODE_MACRO:
@@ -1436,9 +1554,9 @@
             reqFocusMode = ANDROID_CONTROL_AF_OFF;
             break;
         default:
-            ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
-                    cameraId, focusMode);
-            return BAD_VALUE;
+                ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
+                        cameraId, focusMode);
+                return BAD_VALUE;
     }
     res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
             &reqFocusDistance, 1);
@@ -1623,6 +1741,31 @@
         -1;
 }
 
+const char* Parameters::wbModeEnumToString(uint8_t wbMode) {
+    switch (wbMode) {
+        case ANDROID_CONTROL_AWB_AUTO:
+            return CameraParameters::WHITE_BALANCE_AUTO;
+        case ANDROID_CONTROL_AWB_INCANDESCENT:
+            return CameraParameters::WHITE_BALANCE_INCANDESCENT;
+        case ANDROID_CONTROL_AWB_FLUORESCENT:
+            return CameraParameters::WHITE_BALANCE_FLUORESCENT;
+        case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
+            return CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
+        case ANDROID_CONTROL_AWB_DAYLIGHT:
+            return CameraParameters::WHITE_BALANCE_DAYLIGHT;
+        case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
+            return CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
+        case ANDROID_CONTROL_AWB_TWILIGHT:
+            return CameraParameters::WHITE_BALANCE_TWILIGHT;
+        case ANDROID_CONTROL_AWB_SHADE:
+            return CameraParameters::WHITE_BALANCE_SHADE;
+        default:
+            ALOGE("%s: Unknown AWB mode enum: %d",
+                    __FUNCTION__, wbMode);
+            return "unknown";
+    }
+}
+
 int Parameters::effectModeStringToEnum(const char *effectMode) {
     return
         !effectMode ?
@@ -1720,6 +1863,25 @@
         Parameters::FLASH_MODE_INVALID;
 }
 
+const char *Parameters::flashModeEnumToString(flashMode_t flashMode) {
+    switch (flashMode) {
+        case FLASH_MODE_OFF:
+            return CameraParameters::FLASH_MODE_OFF;
+        case FLASH_MODE_AUTO:
+            return CameraParameters::FLASH_MODE_AUTO;
+        case FLASH_MODE_ON:
+            return CameraParameters::FLASH_MODE_ON;
+        case FLASH_MODE_RED_EYE:
+            return CameraParameters::FLASH_MODE_RED_EYE;
+        case FLASH_MODE_TORCH:
+            return CameraParameters::FLASH_MODE_TORCH;
+        default:
+            ALOGE("%s: Unknown flash mode enum %d",
+                    __FUNCTION__, flashMode);
+            return "unknown";
+    }
+}
+
 Parameters::Parameters::focusMode_t Parameters::focusModeStringToEnum(
         const char *focusMode) {
     return
@@ -1742,6 +1904,29 @@
         Parameters::FOCUS_MODE_INVALID;
 }
 
+const char *Parameters::focusModeEnumToString(focusMode_t focusMode) {
+    switch (focusMode) {
+        case FOCUS_MODE_AUTO:
+            return CameraParameters::FOCUS_MODE_AUTO;
+        case FOCUS_MODE_MACRO:
+            return CameraParameters::FOCUS_MODE_MACRO;
+        case FOCUS_MODE_CONTINUOUS_VIDEO:
+            return CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
+        case FOCUS_MODE_CONTINUOUS_PICTURE:
+            return CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
+        case FOCUS_MODE_EDOF:
+            return CameraParameters::FOCUS_MODE_EDOF;
+        case FOCUS_MODE_INFINITY:
+            return CameraParameters::FOCUS_MODE_INFINITY;
+        case FOCUS_MODE_FIXED:
+            return CameraParameters::FOCUS_MODE_FIXED;
+        default:
+            ALOGE("%s: Unknown focus mode enum: %d",
+                    __FUNCTION__, focusMode);
+            return "unknown";
+    }
+}
+
 status_t Parameters::parseAreas(const char *areasCStr,
         Vector<Parameters::Area> *areas) {
     static const size_t NUM_FIELDS = 5;
diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h
index f830e21..c587ca5 100644
--- a/services/camera/libcameraservice/camera2/Parameters.h
+++ b/services/camera/libcameraservice/camera2/Parameters.h
@@ -23,6 +23,8 @@
 #include <utils/Mutex.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <camera/CameraParameters.h>
 
 #include "CameraMetadata.h"
 
@@ -115,6 +117,7 @@
         LIGHTFX_HDR
     } lightFx;
 
+    CameraParameters params;
     String8 paramsFlattened;
 
     // These parameters are also part of the camera API-visible state, but not
@@ -162,8 +165,26 @@
         int32_t arrayHeight;
         uint8_t bestFaceDetectMode;
         int32_t maxFaces;
+        struct OverrideModes {
+            flashMode_t flashMode;
+            uint8_t     wbMode;
+            focusMode_t focusMode;
+            OverrideModes():
+                    flashMode(FLASH_MODE_INVALID),
+                    wbMode(ANDROID_CONTROL_AWB_OFF),
+                    focusMode(FOCUS_MODE_INVALID) {
+            }
+        };
+        DefaultKeyedVector<uint8_t, OverrideModes> sceneModeOverrides;
     } fastInfo;
 
+    // Quirks information; these are short-lived flags to enable workarounds for
+    // incomplete HAL implementations
+    struct Quirks {
+        bool triggerAfWithAuto;
+        bool useZslFormat;
+    } quirks;
+
     /**
      * Parameter manipulation and setup methods
      */
@@ -185,7 +206,10 @@
             size_t minCount=0, size_t maxCount=0) const;
 
     // Validate and update camera parameters based on new settings
-    status_t set(const String8 &params);
+    status_t set(const String8 &paramString);
+
+    // Retrieve the current settings
+    String8 get() const;
 
     // Update passed-in request for common parameters
     status_t updateRequest(CameraMetadata *request) const;
@@ -208,11 +232,14 @@
     static const char *formatEnumToString(int format);
 
     static int wbModeStringToEnum(const char *wbMode);
+    static const char* wbModeEnumToString(uint8_t wbMode);
     static int effectModeStringToEnum(const char *effectMode);
     static int abModeStringToEnum(const char *abMode);
     static int sceneModeStringToEnum(const char *sceneMode);
     static flashMode_t flashModeStringToEnum(const char *flashMode);
+    static const char* flashModeEnumToString(flashMode_t flashMode);
     static focusMode_t focusModeStringToEnum(const char *focusMode);
+    static const char* focusModeEnumToString(focusMode_t focusMode);
     static status_t parseAreas(const char *areasCStr,
             Vector<Area> *areas);
     static status_t validateAreas(const Vector<Area> &areas,
@@ -232,7 +259,6 @@
     int arrayYToNormalized(int height) const;
     int normalizedXToArray(int x) const;
     int normalizedYToArray(int y) const;
-
 };
 
 // This class encapsulates the Parameters class so that it can only be accessed