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

Commit 8d5bf376 authored by Ivan Vecera's avatar Ivan Vecera Committed by Luca Stefani
Browse files

Camera: Remap camera IDs by property if it is defined

Some legacy camera HALs defines a specific property that defines
camera IDs mapping for particular cameras.

Xiaomi camera HALs exports defines persist.vendor.camera.xiaomi.remapid
that is a string property containing a string of space separated
camera IDs.

For example, on pyxis:
pyxis:/ $ getprop persist.vendor.camera.xiaomi.remapid
0 1 21 20 62 60 63 61 91 90 100 101

This example defines mapping: 0->0, 1->1, 2->21, 3->20, ...

Implement this ID remapping by getting  a value of property named
vendor.camera.remapid. If it is not defined or value of this property
is empty the identity mapping of camera IDs is provided to preserve
existing behavior.

This functionality allows to get rid of camera provider blobs that are
shipped by some devices. Only thing that is needed by a device
maintainer is to either patch an elf blob that defines a real property
name (in case of Xiaomi it is placed in com.qti.chi.override.so) or
the maintainer can provide this property in vendor.prop statically.

The following snipper I'm using for Pyxis:
<code>
'vendor/lib/hw/com.qti.chi.override.so': blob_fixup()
    .binary_regex_replace(
        b'persist.vendor.camera.xiaomi.remapid',
        b'vendor.camera.remapid\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'),

Tested using stock camera, Aperture and this dump:
pyxis:/ $ dumpsys media.camera | head -20

== Service global info: ==

Number of camera devices: 12
Number of normal camera devices: 12
Number of public camera devices visible to API1: 12
    Device 0 maps to "0"
    Device 1 maps to "1"
    Device 2 maps to "20"
    Device 3 maps to "21"
    Device 4 maps to "60"
    Device 5 maps to "61"
    Device 6 maps to "62"
    Device 7 maps to "63"
    Device 8 maps to "90"
    Device 9 maps to "91"
    Device 10 maps to "100"
    Device 11 maps to "101"
Active Camera Clients:
[]

Change-Id: I13a3bd186e7fc48e797e3c6f9039a1dae1fb733f
parent 8526b697
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ cc_library_shared {
        "camera.device@3.3-impl",
        "camera.device@3.4-impl",
        "camera.device@3.5-impl",
        "libbase",
        "libcamera_metadata",
        "libcutils",
        "libhardware",
+44 −1
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
#define LOG_TAG "CamPrvdr@2.4-legacy"
//#define LOG_NDEBUG 0
#include <android/log.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>

#include "LegacyCameraProviderImpl_2_4.h"
#include "CameraDevice_1_0.h"
@@ -25,10 +28,13 @@
#include "CameraDevice_3_5.h"
#include "CameraProvider_2_4.h"
#include <cutils/properties.h>
#include <numeric>
#include <regex>
#include <string.h>
#include <utils/Trace.h>

#define CAMERA_REMAP_IDS_PROPERTY "vendor.camera.remapid"

namespace android {
namespace hardware {
namespace camera {
@@ -265,6 +271,34 @@ LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :

LegacyCameraProviderImpl_2_4::~LegacyCameraProviderImpl_2_4() {}

static std::vector<int> getLegacyCameraIdMap(int numberOfCameras) {
    // Initialize identity mapping
    std::vector<int> cameraIdMap(numberOfCameras);
    std::iota(std::begin(cameraIdMap), std::end(cameraIdMap), 0);

    // Return if property for remap is not defined or is empty
    std::string remapProp = base::GetProperty(CAMERA_REMAP_IDS_PROPERTY, "");
    if (remapProp.empty()) {
        ALOGD("%s: camera IDs remapping property '%s' is empty", __func__,
              CAMERA_REMAP_IDS_PROPERTY);
        return cameraIdMap;
    }

    // Split camera IDs that are separated by space
    std::vector<std::string> idRemap = base::Split(remapProp, " ");

    for (int n = 0; n < numberOfCameras; n++) {
        int mappedId;

        // Replace n-th camera ID in the map if it is defined
        if (n < idRemap.size() && base::ParseInt(idRemap[n], &mappedId)) {
            cameraIdMap[n] = mappedId;
        }
    }

    return cameraIdMap;
}

bool LegacyCameraProviderImpl_2_4::initialize() {
    camera_module_t *rawModule;
    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
@@ -313,9 +347,18 @@ bool LegacyCameraProviderImpl_2_4::initialize() {
    }

    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {

    // Get camera IDs map
    auto cameraIdMap = getLegacyCameraIdMap(mNumberOfLegacyCameras);

    for (int n = 0; n < mNumberOfLegacyCameras; n++) {
        int i = cameraIdMap[n];
        mLegacyCameras.insert(i);

        if (n != i) {
            ALOGI("%s: Camera %d ID remapped to %d", __func__, n, i);
        }

        struct camera_info info;
        auto rc = mModule->getCameraInfo(i, &info);
        if (rc != NO_ERROR) {