Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42a171f9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Handle binder call failure due to static metadata size"

parents 891fc3e4 892e826a
Loading
Loading
Loading
Loading
+71 −3
Original line number Diff line number Diff line
@@ -253,6 +253,14 @@ CameraModule::~CameraModule()
        }
        mCameraInfoMap.removeItemsAt(0);
    }

    while (mPhysicalCameraInfoMap.size() > 0) {
        camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
        if (metadata != NULL) {
            free_camera_metadata(metadata);
        }
        mPhysicalCameraInfoMap.removeItemsAt(0);
    }
}

int CameraModule::init() {
@@ -351,7 +359,14 @@ int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t
            return ret;
        }

        index = mPhysicalCameraInfoMap.add(physicalCameraId, info);
        // The camera_metadata_t returned by get_physical_camera_info could be using
        // more memory than necessary due to unused reserved space. Reduce the
        // size by appending it to a new CameraMetadata object, which internally
        // calls resizeIfNeeded.
        CameraMetadata m;
        m.append(info);
        camera_metadata_t* derivedMetadata = m.release();
        index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
    }

    assert(index != NAME_NOT_FOUND);
@@ -473,6 +488,43 @@ void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
   }
}

bool CameraModule::isLogicalMultiCamera(
        const common::V1_0::helper::CameraMetadata& metadata,
        std::unordered_set<std::string>* physicalCameraIds) {
    if (physicalCameraIds == nullptr) {
        ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
        return false;
    }

    bool isLogicalMultiCamera = false;
    camera_metadata_ro_entry_t capabilities =
            metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
    for (size_t i = 0; i < capabilities.count; i++) {
        if (capabilities.data.u8[i] ==
                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
            isLogicalMultiCamera = true;
            break;
        }
    }

    if (isLogicalMultiCamera) {
        camera_metadata_ro_entry_t entry =
                metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
        const uint8_t* ids = entry.data.u8;
        size_t start = 0;
        for (size_t i = 0; i < entry.count; ++i) {
            if (ids[i] == '\0') {
                if (start != i) {
                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
                    physicalCameraIds->emplace(physicalId);
                }
                start = i + 1;
            }
        }
    }
    return isLogicalMultiCamera;
}

status_t CameraModule::filterOpenErrorCode(status_t err) {
    switch(err) {
        case NO_ERROR:
@@ -487,8 +539,24 @@ status_t CameraModule::filterOpenErrorCode(status_t err) {
}

void CameraModule::removeCamera(int cameraId) {
    free_camera_metadata(const_cast<camera_metadata_t*>(
        mCameraInfoMap.valueFor(cameraId).static_camera_characteristics));
    std::unordered_set<std::string> physicalIds;
    camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
            mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
    common::V1_0::helper::CameraMetadata hidlMetadata(metadata);

    if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
        for (const auto& id : physicalIds) {
            int idInt = std::stoi(id);
            if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
                free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
                mPhysicalCameraInfoMap.removeItem(idInt);
            } else {
                ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
                        __FUNCTION__, id.c_str());
            }
        }
    }
    free_camera_metadata(metadata);
    mCameraInfoMap.removeItem(cameraId);
    mDeviceVersionMap.removeItem(cameraId);
}
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
#ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H
#define CAMERA_COMMON_1_0_CAMERAMODULE_H

#include <string>
#include <unordered_set>

#include <hardware/camera.h>
#include <utils/Mutex.h>
#include <utils/KeyedVector.h>
@@ -69,6 +72,10 @@ public:
    int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams);
    void notifyDeviceStateChange(uint64_t deviceState);

    static bool isLogicalMultiCamera(
            const common::V1_0::helper::CameraMetadata& metadata,
            std::unordered_set<std::string>* physicalCameraIds);

private:
    // Derive camera characteristics keys defined after HAL device version
    static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
+6 −25
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <hardware/gralloc.h>
#include <hardware/gralloc1.h>
#include "CameraDeviceSession.h"
#include "CameraModule.h"

namespace android {
namespace hardware {
@@ -30,6 +31,8 @@ namespace device {
namespace V3_4 {
namespace implementation {

using ::android::hardware::camera::common::V1_0::helper::CameraModule;

CameraDeviceSession::CameraDeviceSession(
    camera3_device_t* device,
    const camera_metadata_t* deviceInfo,
@@ -54,31 +57,9 @@ CameraDeviceSession::CameraDeviceSession(

    mResultBatcher_3_4.setNumPartialResults(mNumPartialResults);

    camera_metadata_entry_t capabilities =
            mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
    bool isLogicalMultiCamera = false;
    for (size_t i = 0; i < capabilities.count; i++) {
        if (capabilities.data.u8[i] ==
                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
            isLogicalMultiCamera = true;
            break;
        }
    }
    if (isLogicalMultiCamera) {
        camera_metadata_entry entry =
                mDeviceInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
        const uint8_t* ids = entry.data.u8;
        size_t start = 0;
        for (size_t i = 0; i < entry.count; ++i) {
            if (ids[i] == '\0') {
                if (start != i) {
                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
                    mPhysicalCameraIds.emplace(physicalId);
                }
                start = i + 1;
            }
        }
    }
    // Parse and store current logical camera's physical ids.
    (void)CameraModule::isLogicalMultiCamera(mDeviceInfo, &mPhysicalCameraIds);

}

CameraDeviceSession::~CameraDeviceSession() {