EmulatedCamera: Various CTS related fixes

Fix some obvious issues related to Camera
CTS.

Bug: 131342297
Test: Camera CTS
Change-Id: If0f0dc7c6f48f4e3637c836f6b5ef3904c537baa
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
index e1d926b..943c61f 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.cpp
@@ -33,6 +33,7 @@
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW,
     ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
+    ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
     //TODO: Support more capabilities out-of-the box
 };
 
@@ -92,9 +93,9 @@
         mAETrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
     }
 
-    nsecs_t minFrameDuration = getClosestValue(s2ns(1.f / fpsRange.maxFPS),
+    nsecs_t minFrameDuration = getClosestValue(ms2ns(1000 / fpsRange.maxFPS),
             EmulatedSensor::kSupportedFrameDurationRange[0], mSensorMaxFrameDuration);
-    nsecs_t maxFrameDuration = getClosestValue(s2ns(1.f / fpsRange.minFPS),
+    nsecs_t maxFrameDuration = getClosestValue(ms2ns(1000 / fpsRange.minFPS),
             EmulatedSensor::kSupportedFrameDurationRange[0], mSensorMaxFrameDuration);
     mSensorFrameDuration = (maxFrameDuration + minFrameDuration) / 2;
     // Use a different AE target exposure for face priority mode
@@ -166,6 +167,187 @@
     return OK;
 }
 
+status_t EmulatedRequestState::processAWB() {
+    if (((mAWBMode == ANDROID_CONTROL_AWB_MODE_OFF) ||
+                (mControlMode == ANDROID_CONTROL_MODE_OFF)) && mSupportsManualSensor) {
+        //TODO: Add actual manual support
+    } else if (mIsBackwardCompatible) {
+        camera_metadata_ro_entry_t entry;
+        auto ret = mRequestSettings->Get(ANDROID_CONTROL_AWB_LOCK, &entry);
+        if ((ret == OK) && (entry.count == 1)) {
+            mAWBLock = entry.data.u8[0];
+        } else {
+            mAWBLock = ANDROID_CONTROL_AWB_LOCK_OFF;
+        }
+
+        if (mAELock == ANDROID_CONTROL_AE_LOCK_ON) {
+            mAWBState = ANDROID_CONTROL_AWB_STATE_LOCKED;
+        } else {
+            mAWBState = ANDROID_CONTROL_AWB_STATE_CONVERGED;
+        }
+    } else {
+        // No color output support no need for AWB
+    }
+
+    return OK;
+}
+
+status_t EmulatedRequestState::processAF() {
+    camera_metadata_ro_entry entry;
+
+    if (mAFMode == ANDROID_CONTROL_AF_MODE_OFF) {
+        // TODO: Manual lens control
+        mAFState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+        return OK;
+    }
+
+    auto ret = mRequestSettings->Get(ANDROID_CONTROL_AF_TRIGGER, &entry);
+    if ((ret == OK) && (entry.count == 1)) {
+        mAFTrigger = entry.data.u8[0];
+    } else {
+        mAFTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
+    }
+
+    /**
+     * Simulate AF triggers. Transition at most 1 state per frame.
+     * - Focusing always succeeds (goes into locked, or PASSIVE_SCAN).
+     */
+
+    bool afTriggerStart = false;
+    switch (mAFTrigger) {
+        case ANDROID_CONTROL_AF_TRIGGER_IDLE:
+            break;
+        case ANDROID_CONTROL_AF_TRIGGER_START:
+            afTriggerStart = true;
+            break;
+        case ANDROID_CONTROL_AF_TRIGGER_CANCEL:
+            // Cancel trigger always transitions into INACTIVE
+            mAFState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+
+            // Stay in 'inactive' until at least next frame
+            return OK;
+        default:
+            ALOGE("%s: Unknown af trigger value %d", __FUNCTION__, mAFTrigger);
+            return BAD_VALUE;
+    }
+
+    // If we get down here, we're either in an autofocus mode
+    //  or in a continuous focus mode (and no other modes)
+    switch (mAFState) {
+        case ANDROID_CONTROL_AF_STATE_INACTIVE:
+            if (afTriggerStart) {
+                switch (mAFMode) {
+                    case ANDROID_CONTROL_AF_MODE_AUTO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_MACRO:
+                        mAFState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
+                        break;
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                        mAFState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                        break;
+                }
+            } else {
+                // At least one frame stays in INACTIVE
+                if (!mAFModeChanged) {
+                    switch (mAFMode) {
+                        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                            // fall-through
+                        case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                            mAFState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
+                            break;
+                    }
+                }
+            }
+            break;
+        case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
+            /**
+             * When the AF trigger is activated, the algorithm should finish
+             * its PASSIVE_SCAN if active, and then transition into AF_FOCUSED
+             * or AF_NOT_FOCUSED as appropriate
+             */
+            if (afTriggerStart) {
+                // Randomly transition to focused or not focused
+                if (rand() % 3) {
+                    mAFState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                } else {
+                    mAFState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                }
+            }
+            /**
+             * When the AF trigger is not involved, the AF algorithm should
+             * start in INACTIVE state, and then transition into PASSIVE_SCAN
+             * and PASSIVE_FOCUSED states
+             */
+            else {
+               // Randomly transition to passive focus
+                if (rand() % 3 == 0) {
+                    mAFState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
+                }
+            }
+
+            break;
+        case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
+            if (afTriggerStart) {
+                // Randomly transition to focused or not focused
+                if (rand() % 3) {
+                    mAFState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+                } else {
+                    mAFState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+                }
+            }
+            // TODO: initiate passive scan (PASSIVE_SCAN)
+            break;
+        case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
+            // Simulate AF sweep completing instantaneously
+
+            // Randomly transition to focused or not focused
+            if (rand() % 3) {
+                mAFState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+            } else {
+                mAFState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+            }
+            break;
+        case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+            if (afTriggerStart) {
+                switch (mAFMode) {
+                    case ANDROID_CONTROL_AF_MODE_AUTO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_MACRO:
+                        mAFState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
+                        break;
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                        // continuous autofocus => trigger start has no effect
+                        break;
+                }
+            }
+            break;
+        case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+            if (afTriggerStart) {
+                switch (mAFMode) {
+                    case ANDROID_CONTROL_AF_MODE_AUTO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_MACRO:
+                        mAFState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
+                        break;
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                        // fall-through
+                    case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                        // continuous autofocus => trigger start has no effect
+                        break;
+                }
+            }
+            break;
+        default:
+            ALOGE("%s: Bad af state %d", __FUNCTION__, mAFState);
+    }
+
+    return OK;
+}
+
 status_t EmulatedRequestState::processAE() {
     camera_metadata_ro_entry_t entry;
     if (((mAEMode == ANDROID_CONTROL_AE_MODE_OFF) || (mControlMode == ANDROID_CONTROL_MODE_OFF)) &&
@@ -179,7 +361,7 @@
                 ALOGE("%s: Sensor exposure time: %" PRId64 " not within supported range[%"
                         PRId64 ", %" PRId64 "]", __FUNCTION__, entry.data.i64[0],
                             mSensorExposureTimeRange.first, mSensorExposureTimeRange.second);
-                return BAD_VALUE;
+                // Use last valid value
             }
         }
 
@@ -193,10 +375,14 @@
                         PRId64 ", %" PRId64 "]", __FUNCTION__, entry.data.i64[0],
                             EmulatedSensor::kSupportedFrameDurationRange[0],
                             mSensorMaxFrameDuration);
-                return BAD_VALUE;
+                // Use last valid value
             }
         }
 
+        if (mSensorFrameDuration < mSensorExposureTime) {
+            mSensorFrameDuration = mSensorExposureTime;
+        }
+
         ret = mRequestSettings->Get(ANDROID_SENSOR_SENSITIVITY, &entry);
         if ((ret == OK) && (entry.count == 1)) {
             if ((entry.data.i32[0] >= mSensorSensitivityRange.first) &&
@@ -206,7 +392,7 @@
                 ALOGE("%s: Sensor sensitivity: %d not within supported range[%d, %d]", __FUNCTION__,
                         entry.data.i32[0], mSensorSensitivityRange.first,
                         mSensorSensitivityRange.second);
-                return BAD_VALUE;
+                // Use last valid value
             }
         }
         mAEState = ANDROID_CONTROL_AE_STATE_INACTIVE;
@@ -280,6 +466,7 @@
         ret = mRequestSettings->Get(ANDROID_CONTROL_AF_MODE, &entry);
         if ((ret == OK) && (entry.count == 1)) {
             if (mAvailableAFModes.find(entry.data.u8[0]) != mAvailableAFModes.end()) {
+                mAFModeChanged = mAFMode != entry.data.u8[0];
                 mAFMode = entry.data.u8[0];
             } else {
                 ALOGE("%s: AF mode: %d not supported!", __FUNCTION__, entry.data.u8[0]);
@@ -291,6 +478,7 @@
         if (it != mSceneOverrides.end()) {
             mAEMode = it->second.aeMode;
             mAWBMode = it->second.awbMode;
+            mAFModeChanged = mAFMode != entry.data.u8[0];
             mAFMode = it->second.afMode;
         } else {
             ALOGW("%s: Scene %d has no scene overrides using the currently active 3A modes!",
@@ -303,6 +491,16 @@
         return ret;
     }
 
+    ret = processAWB();
+    if (ret != OK) {
+        return ret;
+    }
+
+    ret = processAF();
+    if (ret != OK) {
+        return ret;
+    }
+
     sensorSettings->exposureTime = mSensorExposureTime;
     sensorSettings->frameDuration = mSensorFrameDuration;
     sensorSettings->gain = mSensorSensitivity;
@@ -317,8 +515,9 @@
     result->camera_id = mCameraId;
     result->pipeline_id = pipelineId;
     result->frame_number = frameNumber;
-    result->result_metadata = request.settings != nullptr ?
-            HalCameraMetadata::Clone(request.settings.get()) : HalCameraMetadata::Create(1, 10);
+    result->result_metadata = HalCameraMetadata::Clone(mRequestSettings.get());
+
+    // Results supported on all emulated devices
     result->result_metadata->Set(ANDROID_REQUEST_PIPELINE_DEPTH, &mMaxPipelineDepth, 1);
     result->result_metadata->Set(ANDROID_CONTROL_MODE, &mControlMode, 1);
     result->result_metadata->Set(ANDROID_CONTROL_AF_MODE, &mAFMode, 1);
@@ -327,13 +526,21 @@
     result->result_metadata->Set(ANDROID_CONTROL_AWB_STATE, &mAWBState, 1);
     result->result_metadata->Set(ANDROID_CONTROL_AE_MODE, &mAEMode, 1);
     result->result_metadata->Set(ANDROID_CONTROL_AE_STATE, &mAEState, 1);
-    result->result_metadata->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &mAETrigger, 1);
     int32_t fpsRange[] = {mAETargetFPS.minFPS, mAETargetFPS.maxFPS};
     result->result_metadata->Set(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, fpsRange,
             ARRAY_SIZE(fpsRange));
+
+    // Results depending on device capability and features
+    if (mIsBackwardCompatible) {
+        result->result_metadata->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &mAETrigger, 1);
+        result->result_metadata->Set(ANDROID_CONTROL_AF_TRIGGER, &mAFTrigger, 1);
+    }
     if (mAELockAvailable && mReportAELock) {
         result->result_metadata->Set(ANDROID_CONTROL_AE_LOCK, &mAELock, 1);
     }
+    if (mAWBLockAvailable && mReportAWBLock) {
+        result->result_metadata->Set(ANDROID_CONTROL_AWB_LOCK, &mAWBLock, 1);
+    }
     if (mScenesSupported) {
         result->result_metadata->Set(ANDROID_CONTROL_SCENE_MODE, &mSceneMode, 1);
     }
@@ -524,6 +731,22 @@
         return BAD_VALUE;
     }
 
+    if (mAvailableRequests.find(ANDROID_CONTROL_AF_MODE) == mAvailableRequests.end()) {
+        ALOGE("%s: Clients must be able to set AF mode!", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (mIsBackwardCompatible) {
+        if (mAvailableRequests.find(ANDROID_CONTROL_AF_TRIGGER) == mAvailableRequests.end()) {
+            ALOGE("%s: Clients must be able to set AF trigger!", __FUNCTION__);
+            return BAD_VALUE;
+        }
+        if (mAvailableResults.find(ANDROID_CONTROL_AF_TRIGGER) == mAvailableResults.end()) {
+            ALOGE("%s: AF trigger must be reported!", __FUNCTION__);
+            return BAD_VALUE;
+        }
+    }
+
     if (mAvailableResults.find(ANDROID_CONTROL_AF_MODE) == mAvailableResults.end()) {
         ALOGE("%s: AF mode must be reported!", __FUNCTION__);
         return BAD_VALUE;
@@ -534,6 +757,10 @@
         return BAD_VALUE;
     }
 
+    bool autoModePresent = mAvailableAFModes.find(ANDROID_CONTROL_AF_MODE_AUTO) !=
+            mAvailableAFModes.end();
+    mAFSupported = autoModePresent && (mMinimumFocusDistance > .0f);
+
     return OK;
 }
 status_t EmulatedRequestState::initializeControlAWBDefaults() {
@@ -561,6 +788,15 @@
         return BAD_VALUE;
     }
 
+    ret = mStaticMetadata->Get(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &entry);
+    if ((ret == OK) && (entry.count == 1)) {
+        mAWBLockAvailable = entry.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
+    } else {
+        ALOGV("%s: No available AWB lock!", __FUNCTION__);
+        mAWBLockAvailable = false;
+    }
+    mReportAWBLock = mAvailableResults.find(ANDROID_CONTROL_AWB_LOCK) != mAvailableResults.end();
+
     return OK;
 }
 
@@ -617,15 +853,18 @@
         }
     }
 
-    if (mAvailableRequests.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) ==
-            mAvailableRequests.end()) {
-        ALOGE("%s: Clients must be able to set AE pre-capture trigger!", __FUNCTION__);
-        return BAD_VALUE;
-    }
+    if (mIsBackwardCompatible) {
+        if (mAvailableRequests.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) ==
+                mAvailableRequests.end()) {
+            ALOGE("%s: Clients must be able to set AE pre-capture trigger!", __FUNCTION__);
+            return BAD_VALUE;
+        }
 
-    if (mAvailableResults.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) == mAvailableResults.end()) {
-        ALOGE("%s: AE pre-capture trigger must be reported!", __FUNCTION__);
-        return BAD_VALUE;
+        if (mAvailableResults.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER) ==
+                mAvailableResults.end()) {
+            ALOGE("%s: AE pre-capture trigger must be reported!", __FUNCTION__);
+            return BAD_VALUE;
+        }
     }
 
     ret = mStaticMetadata->Get(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, &entry);
@@ -711,11 +950,11 @@
         controlMode = ANDROID_CONTROL_MODE_AUTO;
         aeMode = ANDROID_CONTROL_AE_MODE_ON;
         awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
-        afMode = ANDROID_CONTROL_AF_MODE_OFF;
+        afMode = mAFSupported ? ANDROID_CONTROL_AF_MODE_AUTO : ANDROID_CONTROL_AF_MODE_OFF;
         sceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
         uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
+        uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
         int32_t aeTargetFPS [] = {mAvailableFPSRanges[0].minFPS, mAvailableFPSRanges[0].maxFPS};
-        uint8_t aeTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
         switch(templateIdx) {
             case RequestTemplate::kManual:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
@@ -747,15 +986,23 @@
             mDefaultRequests[idx]->Set(ANDROID_CONTROL_AE_MODE, &aeMode, 1);
             mDefaultRequests[idx]->Set(ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
             mDefaultRequests[idx]->Set(ANDROID_CONTROL_AF_MODE, &afMode, 1);
-            mDefaultRequests[idx]->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aeTrigger, 1);
             mDefaultRequests[idx]->Set(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFPS,
                     ARRAY_SIZE(aeTargetFPS));
             if (mAELockAvailable) {
                 mDefaultRequests[idx]->Set(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
             }
+            if (mAWBLockAvailable) {
+                mDefaultRequests[idx]->Set(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
+            }
             if (mScenesSupported) {
                 mDefaultRequests[idx]->Set(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
             }
+            if (mIsBackwardCompatible) {
+                uint8_t aeTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
+                mDefaultRequests[idx]->Set(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aeTrigger, 1);
+                uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
+                mDefaultRequests[idx]->Set(ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1);
+            }
         }
     }
 
@@ -776,6 +1023,19 @@
     return initializeControlDefaults();
 }
 
+status_t EmulatedRequestState::initializeLensDefaults() {
+    camera_metadata_ro_entry_t entry;
+    auto ret = mStaticMetadata->Get(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &entry);
+    if ((ret == OK) && (entry.count == 1)) {
+        mMinimumFocusDistance = entry.data.f[0];
+    } else {
+        ALOGW("%s: No available minimum focus distance assuming fixed focus!", __FUNCTION__);
+        mMinimumFocusDistance = .0f;
+    }
+
+    return initializeFlashDefaults();
+}
+
 status_t EmulatedRequestState::initializeInfoDefaults() {
     camera_metadata_ro_entry_t entry;
     auto ret = mStaticMetadata->Get(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
@@ -791,7 +1051,7 @@
 
     mSupportedHWLevel = entry.data.u8[0];
 
-    return initializeFlashDefaults();
+    return initializeLensDefaults();
 }
 
 status_t EmulatedRequestState::initializeRequestDefaults() {
diff --git a/devices/EmulatedCamera/hwl/EmulatedRequestState.h b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
index 1b4d670..9669661 100644
--- a/devices/EmulatedCamera/hwl/EmulatedRequestState.h
+++ b/devices/EmulatedCamera/hwl/EmulatedRequestState.h
@@ -65,8 +65,11 @@
     status_t initializeControlSceneDefaults();
     status_t initializeControlefaults();
     status_t initializeInfoDefaults();
+    status_t initializeLensDefaults();
 
     status_t processAE();
+    status_t processAF();
+    status_t processAWB();
     status_t doFakeAE();
 
     std::mutex mRequestStateMutex;
@@ -116,7 +119,9 @@
     uint8_t mAELock = ANDROID_CONTROL_AE_LOCK_OFF;
     uint8_t mAEState = ANDROID_CONTROL_AE_STATE_INACTIVE;
     uint8_t mAWBState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
+    uint8_t mAWBLock = ANDROID_CONTROL_AWB_LOCK_OFF;
     uint8_t mAFState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+    uint8_t mAFTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
     uint8_t mAETrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
     FPSRange mAETargetFPS;
     bool mAELockAvailable = false;
@@ -129,6 +134,10 @@
     const float kExposureWanderMin = -2;
     const float kExposureWanderMax = 1;
     nsecs_t mAETargetExposureTime = EmulatedSensor::kDefaultExposureTime;
+    bool mAWBLockAvailable = false;
+    bool mReportAWBLock = false;
+    bool mAFModeChanged = false;
+    bool mAFSupported = false;
 
     // android.flash.*
     bool mIsFlashSupported = false;
@@ -149,6 +158,9 @@
     static const size_t kTemplateCount = static_cast<size_t>(RequestTemplate::kManual) + 1;
     std::unique_ptr<HalCameraMetadata> mDefaultRequests[kTemplateCount];
 
+    // android.lens.*
+    float mMinimumFocusDistance = 0.f;
+
     uint32_t mCameraId;
 
     EmulatedRequestState(const EmulatedRequestState&) = delete;
diff --git a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
index fda8ec9..2a48048 100644
--- a/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
+++ b/devices/EmulatedCamera/hwl/EmulatedSensor.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 //#define LOG_NNDEBUG 0
 #define LOG_TAG "EmulatedSensor"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
 
 #ifdef LOG_NNDEBUG
 #define ALOGVV(...) ALOGV(__VA_ARGS__)
@@ -25,6 +26,7 @@
 #endif
 
 #include <utils/Log.h>
+#include <utils/Trace.h>
 
 #include <cmath>
 #include <cstdlib>
@@ -332,6 +334,7 @@
 }
 
 bool EmulatedSensor::threadLoop() {
+    ATRACE_CALL();
     /**
      * Sensor capture operation main loop.
      *
@@ -399,9 +402,6 @@
                     break;
                 case HAL_PIXEL_FORMAT_BLOB:
                     if ((*b)->dataSpace == HAL_DATASPACE_V0_JFIF) {
-                        // Add auxillary buffer of the right size
-                        // Assumes only one BLOB (JPEG) buffer in
-                        // mNextCapturedBuffers
                         auto jpegInput = std::make_unique<JpegRGBInput>();
                         jpegInput->width = (*b)->width;
                         jpegInput->height = (*b)->height;
@@ -484,6 +484,7 @@
 };
 
 void EmulatedSensor::captureRaw(uint8_t *img, uint32_t gain, uint32_t width) {
+    ATRACE_CALL();
     float totalGain = gain / 100.0 * kBaseGainFactor;
     float noiseVarGain = totalGain * totalGain;
     float readNoiseVar =
@@ -527,6 +528,7 @@
 }
 
 void EmulatedSensor::captureRGBA(uint8_t *img, uint32_t gain, uint32_t width,  uint32_t stride) {
+    ATRACE_CALL();
     float totalGain = gain / 100.0 * kBaseGainFactor;
     // In fixed-point math, calculate total scaling from electrons to 8bpp
     int scale64x = 64 * totalGain * 255 / mChars.maxRawValue;
@@ -556,6 +558,7 @@
 }
 
 void EmulatedSensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t width, uint32_t stride) {
+    ATRACE_CALL();
     float totalGain = gain / 100.0 * kBaseGainFactor;
     // In fixed-point math, calculate total scaling from electrons to 8bpp
     int scale64x = 64 * totalGain * 255 / mChars.maxRawValue;
@@ -584,6 +587,7 @@
 }
 
 void EmulatedSensor::captureNV21(YCbCrPlanes yuvLayout, uint32_t gain, uint32_t width) {
+    ATRACE_CALL();
     float totalGain = gain / 100.0 * kBaseGainFactor;
     // Using fixed-point math with 6 bits of fractional precision.
     // In fixed-point math, calculate total scaling from electrons to 8bpp
@@ -638,6 +642,7 @@
 }
 
 void EmulatedSensor::captureDepth(uint8_t *img, uint32_t gain, uint32_t width, uint32_t stride) {
+    ATRACE_CALL();
     float totalGain = gain / 100.0 * kBaseGainFactor;
     // In fixed-point math, calculate scaling factor to 13bpp millimeters
     int scale64x = 64 * totalGain * 8191 / mChars.maxRawValue;
diff --git a/devices/EmulatedCamera/hwl/camera.json b/devices/EmulatedCamera/hwl/camera.json
index 5a1dfa7..8032137 100644
--- a/devices/EmulatedCamera/hwl/camera.json
+++ b/devices/EmulatedCamera/hwl/camera.json
@@ -9,9 +9,9 @@
       "android.sensor.info.physicalSize":
         ["3.20000005", "2.40000010"],
       "android.sensor.info.pixelArraySize":
-        ["1600", "1200"],
+        ["1632", "1226"],
       "android.sensor.info.activeArraySize":
-        ["0", "0", "1600", "1200"],
+        ["0", "0", "1632", "1226"],
       "android.sensor.orientation":
         "90",
       "android.sensor.info.timestampSource":
@@ -49,20 +49,24 @@
       "android.tonemap.availableToneMapModes":
         ["0", "1", "2"],
       "android.scaler.availableStreamConfigurations":
-        ["33", "1600", "1200", "0",
+        ["33", "1632", "1226", "0",
+        "33", "1280", "720", "0",
         "34", "320", "240", "0",
         "35", "320", "240", "0",
         "33", "320", "240", "0",
         "34", "640", "480", "0",
         "35", "640", "480", "0",
         "33", "640", "480", "0",
-        "32", "1600", "1200", "0",
-        "34", "1600", "1200", "0",
-        "35", "1600", "1200", "0",
+        "34", "1280", "720", "0",
+        "34", "1632", "1226", "0",
+        "35", "1280", "720", "0",
+        "35", "1632", "1226", "0",
         "1", "1600", "1200", "0"],
       "android.scaler.availableMinFrameDurations":
-        ["33", "1600",
-        "1200", "33331760",
+        ["33", "1632",
+        "1226", "33331760",
+        "33", "1280",
+        "720", "33331760",
         "34", "320",
         "240", "33331760",
         "35", "320",
@@ -75,17 +79,21 @@
         "480", "33331760",
         "33", "640",
         "480", "33331760",
-        "32", "1600",
-        "1200", "33331760",
-        "34", "1600",
-        "1200", "33331760",
-        "35", "1600",
-        "1200", "33331760",
+        "34", "1280",
+        "720", "33331760",
+        "34", "1632",
+        "1226", "33331760",
+        "35", "1280",
+        "720", "33331760",
+        "35", "1632",
+        "1226", "33331760",
         "1", "1600",
         "1200", "33331760"],
       "android.scaler.availableStallDurations":
-        ["33", "1600",
-        "1200", "33331760",
+        ["33", "1632",
+        "1226", "33331760",
+        "33", "1280",
+        "720", "33331760",
         "34", "320",
         "240", "0",
         "35", "320",
@@ -98,12 +106,14 @@
         "480", "0",
         "33", "640",
         "480", "33331760",
-        "32", "1600",
-        "1200", "33331760",
-        "34", "1600",
-        "1200", "0",
-        "35", "1600",
-        "1200", "0",
+        "34", "1280",
+        "720", "0",
+        "34", "1632",
+        "1226", "0",
+        "35", "1280",
+        "720", "0",
+        "35", "1632",
+        "1226", "0",
         "1", "1600",
         "1200", "0"],
       "android.scaler.croppingType":
@@ -140,8 +150,8 @@
       "android.control.aeCompensationRange":
         ["-9", "9"],
       "android.control.aeAvailableTargetFpsRanges":
-        ["5", "30", "15", "30",
-        "15", "15", "30", "30"],
+        ["15", "15", "5", "30",
+        "15", "30", "30", "30"],
       "android.control.aeAvailableAntibandingModes":
         ["0", "3"],
       "android.control.aeLockAvailable":
@@ -171,7 +181,7 @@
       "android.request.partialResultCount":
         "1",
       "android.request.availableCapabilities":
-        ["0", "1", "2", "5"],
+        ["0", "1", "2", "5", "6"],
       "android.request.availableRequestKeys":
         ["786435", "786433", "786432", "524290",
         "524291", "524288", "524289", "524292",
@@ -228,5 +238,5 @@
       "android.request.availableSessionKeys":
         ["786435"],
       "android.sensor.info.preCorrectionActiveArraySize":
-        ["0", "0", "1600", "1200"]
+        ["0", "0", "1632", "1226"]
 }