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

Commit 615e1600 authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

camera (v)ndk: Setup vendor tags if they're not already, while calling getCameraService()



It is possible that by the time CameraManagerGlobal::getCameraService()
is called, cameraservice is up, however camera HAL providers haven't
registered themselves with cameraservice. In this case, the vendor tag
cache will not be available. As a result, we should check and set it up while
checking for cameraserver validity for subsequent calls of
CameraManagerGlobal::getCameraService().

Bug: 368235553

Flag: EXEMPT BUGFIX

Test: Vendor service which comes up before camera HAL registers itself
      with cameraserver can eventually, retrieve vendor tags.

Change-Id: I51ea31c11692498f1c07d7efdc91e4b176f73f27
Signed-off-by: default avatarJayant Chowdhary <jchowdhary@google.com>
parent b6158c5e
Loading
Loading
Loading
Loading
+107 −85
Original line number Diff line number Diff line
@@ -170,7 +170,9 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
}

sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
    if (mCameraService.get() == nullptr) {
    if (mCameraService.get() != nullptr) {
        return mCameraService;
    }
    if (CameraUtils::isCameraServiceDisabled()) {
        return mCameraService;
    }
@@ -182,13 +184,13 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
        ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
        return nullptr;
    }
    sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
    if (mDeathNotifier == nullptr) {
        mDeathNotifier = new DeathNotifier(this);
        }
        binder->linkToDeath(mDeathNotifier);
        mCameraService = interface_cast<hardware::ICameraService>(binder);
    }

        // Setup looper thread to perfrom availiability callbacks
    // Setup looper thread to perform availability callbacks
    if (mCbLooper == nullptr) {
        mCbLooper = new ALooper;
        mCbLooper->setName("C2N-mgr-looper");
@@ -209,11 +211,12 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
    }

    // register ICameraServiceListener
    std::vector<hardware::CameraStatus> cameraStatuses{};
    if (mCameraServiceListener == nullptr) {
        mCameraServiceListener = new CameraServiceListener(this);
        cameraService->addListener(mCameraServiceListener, &cameraStatuses);
    }
        std::vector<hardware::CameraStatus> cameraStatuses{};
        mCameraService->addListener(mCameraServiceListener, &cameraStatuses);

    for (auto& c : cameraStatuses) {
        onStatusChangedLocked(c.status, c.deviceId, c.cameraId);

@@ -222,23 +225,45 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
                                    c.deviceId, c.cameraId, unavailablePhysicalId);
        }
    }

    // setup vendor tags
    if (!setupVendorTags(cameraService)) {
        ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
        return nullptr;
    }

    mCameraService = cameraService;
    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
    return mCameraService;
}

bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
    sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
        binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
    binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
    if (!ret.isOk()) {
        if (ret.serviceSpecificErrorCode() ==
            hardware::ICameraService::ERROR_DEPRECATED_HAL) {
            ALOGW("%s: Camera HAL too old; does not support vendor tags",
                    __FUNCTION__);
            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
        } else {
            ALOGE("%s: Failed to get vendor tag descriptors: %s",
                    __FUNCTION__, ret.toString8().c_str());
        }
        return false;
    }

        if (ret.isOk()) {
    if (0 < desc->getTagCount()) {
        status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
        if (err != OK) {
            ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
                    __FUNCTION__, strerror(-err), err);
            return false;
        }
    } else {
        sp<VendorTagDescriptorCache> cache =
                new VendorTagDescriptorCache();
        binder::Status res =
                        mCameraService->getCameraVendorTagCache(
                cameraService->getCameraVendorTagCache(
                        /*out*/cache.get());
        if (res.serviceSpecificErrorCode() ==
                hardware::ICameraService::ERROR_DISCONNECTED) {
@@ -252,25 +277,17 @@ sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
                ALOGE("%s: Failed to set vendor tag cache,"
                        "received error %s (%d)", __FUNCTION__,
                        strerror(-err), err);
                return false;
            }
        } else {
            VendorTagDescriptorCache::clearGlobalVendorTagCache();
            ALOGE("%s: Failed to setup vendor tag cache: %s",
                    __FUNCTION__, res.toString8().c_str());
            return false;
        }
    }
        } else if (ret.serviceSpecificErrorCode() ==
                hardware::ICameraService::ERROR_DEPRECATED_HAL) {
            ALOGW("%s: Camera HAL too old; does not support vendor tags",
                    __FUNCTION__);
            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
        } else {
            ALOGE("%s: Failed to get vendor tag descriptors: %s",
                    __FUNCTION__, ret.toString8().c_str());
        }
    }
    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
    return mCameraService;

    return true;
}

void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
@@ -290,6 +307,8 @@ void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
                                      key.cameraId);
        }
        cm->mCameraService.clear();
        cm->mCameraServiceListener.clear();
        cm->mDeathNotifier.clear();
        // TODO: consider adding re-connect call here?
    }
}
@@ -398,6 +417,9 @@ void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceConte
bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
    bool camera2Support = false;
    auto cs = getCameraServiceLocked();
    if (cs == nullptr) {
        return false;
    }
    binder::Status serviceRet =
        cs->supportsCameraApi(cameraId,
                hardware::ICameraService::API_VERSION_2, &camera2Support);
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ class CameraManagerGlobal final : public RefBase {
    template <class T>
    void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);

    bool setupVendorTags(sp<hardware::ICameraService> &cameraService);

    class DeathNotifier : public IBinder::DeathRecipient {
      public:
        explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
+26 −28
Original line number Diff line number Diff line
@@ -194,11 +194,11 @@ static bool isCameraServiceDisabled() {
    return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
}

bool CameraManagerGlobal::setupVendorTags() {
bool CameraManagerGlobal::setupVendorTags(std::shared_ptr<ICameraService> &cameraService) {
    sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
    Status status = Status::NO_ERROR;
    std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
    ScopedAStatus remoteRet = mCameraService->getCameraVendorTagSections(&providerIdsAndVts);
    ScopedAStatus remoteRet = cameraService->getCameraVendorTagSections(&providerIdsAndVts);

    if (!remoteRet.isOk()) {
        if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
@@ -261,15 +261,12 @@ std::shared_ptr<ICameraService> CameraManagerGlobal::getCameraService() {
        ALOGE("%s: Could not get ICameraService instance.", __FUNCTION__);
        return nullptr;
    }

    if (mDeathRecipient.get() == nullptr) {
        mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
                AIBinder_DeathRecipient_new(CameraManagerGlobal::binderDeathCallback));
    }
        AIBinder_linkToDeath(cameraService->asBinder().get(),
                             mDeathRecipient.get(), /*cookie=*/ this);

    mCameraService = cameraService;
    }

    // Setup looper thread to perform availability callbacks
    if (mCbLooper == nullptr) {
@@ -291,16 +288,12 @@ std::shared_ptr<ICameraService> CameraManagerGlobal::getCameraService() {
        mCbLooper->registerHandler(mHandler);
    }

    std::vector<CameraStatusAndId> cameraStatuses;
    // register ICameraServiceListener
    if (mCameraServiceListener == nullptr) {
        mCameraServiceListener = ndk::SharedRefBase::make<CameraServiceListener>(weak_from_this());
    }

    std::vector<CameraStatusAndId> cameraStatuses;
    Status status = Status::NO_ERROR;
    ScopedAStatus remoteRet = mCameraService->addListener(mCameraServiceListener,
        ScopedAStatus remoteRet = cameraService->addListener(mCameraServiceListener,
                                                            &cameraStatuses);

        if (!remoteRet.isOk()) {
            if (remoteRet.getExceptionCode() == EX_SERVICE_SPECIFIC) {
                Status errStatus = static_cast<Status>(remoteRet.getServiceSpecificError());
@@ -310,13 +303,9 @@ std::shared_ptr<ICameraService> CameraManagerGlobal::getCameraService() {
                ALOGE("%s: Transaction failed when adding listener to camera service: %d",
                    __FUNCTION__, remoteRet.getExceptionCode());
            }
    }

    // Setup vendor tags
    if (!setupVendorTags()) {
        ALOGE("Unable to set up vendor tags");
            return nullptr;
        }
    }

    for (auto& csi: cameraStatuses){
        onStatusChangedLocked(csi.deviceStatus, csi.cameraId);
@@ -326,6 +315,13 @@ std::shared_ptr<ICameraService> CameraManagerGlobal::getCameraService() {
                                  csi.cameraId, unavailablePhysicalId);
        }
    }

   // Setup vendor tags
    if (!setupVendorTags(cameraService)) {
        ALOGE("Unable to set up vendor tags");
        return nullptr;
    }
    mCameraService = cameraService;
    return mCameraService;
}

@@ -346,6 +342,8 @@ void CameraManagerGlobal::binderDeathCallback(void* /*cookie*/) {
        instance->onStatusChangedLocked(deviceStatus, cameraId);
    }
    instance->mCameraService.reset();
    instance->mDeathRecipient.release();
    instance->mCameraServiceListener.reset();
    // TODO: consider adding re-connect call here?
}

+1 −1
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ class CameraManagerGlobal final: public std::enable_shared_from_this<CameraManag
                         const std::string &physicalCameraId);
    void onStatusChangedLocked(const CameraDeviceStatus &status, const std::string &cameraId,
                               const std::string &physicalCameraId);
    bool setupVendorTags();
    bool setupVendorTags(std::shared_ptr<ICameraService> &cameraService);

    // Utils for status
    static bool validStatus(CameraDeviceStatus status);