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

Commit a29c135c authored by Peter Kalauskas's avatar Peter Kalauskas
Browse files

Camera: Support lazy HALs

Drop camera HAL references when unused.

Use ro.camera.enableLazyHal property to toggle behavior on or off.
 * If true, the cameraserver drops references to ICameraProvider HALs
   when they are not being used for either camera or torch.
 * If false (or unset), stores a strong reference to each ICameraProvider
   that is registered. This is the same as the old behavior.

Bug: 79374634
Test: Apply CL that lets camera HAL exit when unused. Open camera/enable
      torch, close camera/disable torch, check ps -A to see if HAL exits.
Change-Id: I1842f9bf9e862ab74e4ec8aa72fc46fc47782ed0
parent b7bd4383
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -2215,6 +2215,8 @@ binder::Status CameraService::BasicClient::disconnect() {
    sCameraService->removeByClient(this);
    sCameraService->removeByClient(this);
    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
    sCameraService->logDisconnected(mCameraIdStr, mClientPid,
            String8(mClientPackageName));
            String8(mClientPackageName));
    sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
            mCameraIdStr.c_str());


    sp<IBinder> remote = getRemote();
    sp<IBinder> remote = getRemote();
    if (remote != nullptr) {
    if (remote != nullptr) {
+267 −68

File changed.

Preview size limit exceeded, changes collapsed.

+83 −16
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
#define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H


#include <vector>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <unordered_set>
#include <string>
#include <string>
#include <mutex>
#include <mutex>
@@ -110,6 +111,14 @@ public:
        virtual void onNewProviderRegistered() = 0;
        virtual void onNewProviderRegistered() = 0;
    };
    };


    /**
     * Represents the mode a camera device is currently in
     */
    enum class DeviceMode {
        TORCH,
        CAMERA
    };

    /**
    /**
     * Initialize the manager and give it a status listener; optionally accepts a service
     * Initialize the manager and give it a status listener; optionally accepts a service
     * interaction proxy.
     * interaction proxy.
@@ -182,7 +191,7 @@ public:
    /**
    /**
     * Check if a given camera device support setTorchMode API.
     * Check if a given camera device support setTorchMode API.
     */
     */
    bool supportSetTorchMode(const std::string &id);
    bool supportSetTorchMode(const std::string &id) const;


    /**
    /**
     * Turn on or off the flashlight on a given camera device.
     * Turn on or off the flashlight on a given camera device.
@@ -212,6 +221,17 @@ public:
            /*out*/
            /*out*/
            sp<hardware::camera::device::V1_0::ICameraDevice> *session);
            sp<hardware::camera::device::V1_0::ICameraDevice> *session);


    /**
     * Save the ICameraProvider while it is being used by a camera or torch client
     */
    void saveRef(DeviceMode usageType, const std::string &cameraId,
            sp<hardware::camera::provider::V2_4::ICameraProvider> provider);

    /**
     * Notify that the camera or torch is no longer being used by a camera client
     */
    void removeRef(DeviceMode usageType, const std::string &cameraId);

    /**
    /**
     * IServiceNotification::onRegistration
     * IServiceNotification::onRegistration
     * Invoked by the hardware service manager when a new camera provider is registered
     * Invoked by the hardware service manager when a new camera provider is registered
@@ -259,21 +279,43 @@ private:


    static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
    static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;


    // Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
    // ICameraProvider alive while it is in use by the camera with the given ID for camera
    // capabilities
    std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
            mCameraProviderByCameraId;

    // Mapping from CameraDevice IDs to CameraProviders. This map is used to keep the
    // ICameraProvider alive while it is in use by the camera with the given ID for torch
    // capabilities
    std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>>
            mTorchProviderByCameraId;

    // Lock for accessing mCameraProviderByCameraId and mTorchProviderByCameraId
    std::mutex mProviderInterfaceMapLock;

    struct ProviderInfo :
    struct ProviderInfo :
            virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
            virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
            virtual public hardware::hidl_death_recipient
            virtual public hardware::hidl_death_recipient
    {
    {
        const std::string mProviderName;
        const std::string mProviderName;
        const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
        const metadata_vendor_id_t mProviderTagid;
        const metadata_vendor_id_t mProviderTagid;
        sp<VendorTagDescriptor> mVendorTagDescriptor;
        sp<VendorTagDescriptor> mVendorTagDescriptor;
        bool mSetTorchModeSupported;
        bool mIsRemote;

        // This pointer is used to keep a reference to the ICameraProvider that was last accessed.
        wp<hardware::camera::provider::V2_4::ICameraProvider> mActiveInterface;

        sp<hardware::camera::provider::V2_4::ICameraProvider> mSavedInterface;


        ProviderInfo(const std::string &providerName,
        ProviderInfo(const std::string &providerName,
                sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
                CameraProviderManager *manager);
                CameraProviderManager *manager);
        ~ProviderInfo();
        ~ProviderInfo();


        status_t initialize();
        status_t initialize(sp<hardware::camera::provider::V2_4::ICameraProvider>& interface);

        const sp<hardware::camera::provider::V2_4::ICameraProvider> startProviderInterface();


        const std::string& getType() const;
        const std::string& getType() const;


@@ -308,16 +350,20 @@ private:
            const metadata_vendor_id_t mProviderTagid;
            const metadata_vendor_id_t mProviderTagid;
            bool mIsLogicalCamera;
            bool mIsLogicalCamera;
            std::vector<std::string> mPhysicalIds;
            std::vector<std::string> mPhysicalIds;
            hardware::CameraInfo mInfo;
            sp<IBase> mSavedInterface;


            const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
            const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;


            hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
            hardware::camera::common::V1_0::CameraDeviceStatus mStatus;


            sp<ProviderInfo> mParentProvider;

            bool hasFlashUnit() const { return mHasFlashUnit; }
            bool hasFlashUnit() const { return mHasFlashUnit; }
            virtual status_t setTorchMode(bool enabled) = 0;
            virtual status_t setTorchMode(bool enabled) = 0;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
            virtual bool isAPI1Compatible() const = 0;
            virtual bool isAPI1Compatible() const = 0;
            virtual status_t dumpState(int fd) const = 0;
            virtual status_t dumpState(int fd) = 0;
            virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
            virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
                (void) characteristics;
                (void) characteristics;
                return INVALID_OPERATION;
                return INVALID_OPERATION;
@@ -331,19 +377,23 @@ private:


            virtual status_t isSessionConfigurationSupported(
            virtual status_t isSessionConfigurationSupported(
                    const hardware::camera::device::V3_4::StreamConfiguration &/*configuration*/,
                    const hardware::camera::device::V3_4::StreamConfiguration &/*configuration*/,
                    bool * /*status*/)
                    bool * /*status*/) {
                    const {
                return INVALID_OPERATION;
                return INVALID_OPERATION;
            }
            }


            template<class InterfaceT>
            sp<InterfaceT> startDeviceInterface();

            DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
            DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
                    const std::string &id, const hardware::hidl_version& version,
                    const std::string &id, const hardware::hidl_version& version,
                    const std::vector<std::string>& publicCameraIds,
                    const std::vector<std::string>& publicCameraIds,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost) :
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    sp<ProviderInfo> parentProvider) :
                    mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
                    mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
                    mIsLogicalCamera(false), mResourceCost(resourceCost),
                    mIsLogicalCamera(false), mResourceCost(resourceCost),
                    mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
                    mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
                    mHasFlashUnit(false), mPublicCameraIds(publicCameraIds) {}
                    mParentProvider(parentProvider), mHasFlashUnit(false),
                    mPublicCameraIds(publicCameraIds) {}
            virtual ~DeviceInfo();
            virtual ~DeviceInfo();
        protected:
        protected:
            bool mHasFlashUnit;
            bool mHasFlashUnit;
@@ -351,6 +401,14 @@ private:


            template<class InterfaceT>
            template<class InterfaceT>
            static status_t setTorchMode(InterfaceT& interface, bool enabled);
            static status_t setTorchMode(InterfaceT& interface, bool enabled);

            template<class InterfaceT>
            status_t setTorchModeForDevice(bool enabled) {
                // Don't save the ICameraProvider interface here because we assume that this was
                // called from CameraProviderManager::setTorchMode(), which does save it.
                const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
                return DeviceInfo::setTorchMode(interface, enabled);
            }
        };
        };
        std::vector<std::unique_ptr<DeviceInfo>> mDevices;
        std::vector<std::unique_ptr<DeviceInfo>> mDevices;
        std::unordered_set<std::string> mUniqueCameraIds;
        std::unordered_set<std::string> mUniqueCameraIds;
@@ -366,32 +424,32 @@ private:
        // HALv1-specific camera fields, including the actual device interface
        // HALv1-specific camera fields, including the actual device interface
        struct DeviceInfo1 : public DeviceInfo {
        struct DeviceInfo1 : public DeviceInfo {
            typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT;
            typedef hardware::camera::device::V1_0::ICameraDevice InterfaceT;
            const sp<InterfaceT> mInterface;


            virtual status_t setTorchMode(bool enabled) override;
            virtual status_t setTorchMode(bool enabled) override;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
            //In case of Device1Info assume that we are always API1 compatible
            //In case of Device1Info assume that we are always API1 compatible
            virtual bool isAPI1Compatible() const override { return true; }
            virtual bool isAPI1Compatible() const override { return true; }
            virtual status_t dumpState(int fd) const override;
            virtual status_t dumpState(int fd) override;
            DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId,
            DeviceInfo1(const std::string& name, const metadata_vendor_id_t tagId,
                    const std::string &id, uint16_t minorVersion,
                    const std::string &id, uint16_t minorVersion,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    sp<ProviderInfo> parentProvider,
                    const std::vector<std::string>& publicCameraIds,
                    const std::vector<std::string>& publicCameraIds,
                    sp<InterfaceT> interface);
                    sp<InterfaceT> interface);
            virtual ~DeviceInfo1();
            virtual ~DeviceInfo1();
        private:
        private:
            CameraParameters2 mDefaultParameters;
            CameraParameters2 mDefaultParameters;
            status_t cacheCameraInfo(sp<InterfaceT> interface);
        };
        };


        // HALv3-specific camera fields, including the actual device interface
        // HALv3-specific camera fields, including the actual device interface
        struct DeviceInfo3 : public DeviceInfo {
        struct DeviceInfo3 : public DeviceInfo {
            typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
            typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
            const sp<InterfaceT> mInterface;


            virtual status_t setTorchMode(bool enabled) override;
            virtual status_t setTorchMode(bool enabled) override;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
            virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
            virtual bool isAPI1Compatible() const override;
            virtual bool isAPI1Compatible() const override;
            virtual status_t dumpState(int fd) const override;
            virtual status_t dumpState(int fd) override;
            virtual status_t getCameraCharacteristics(
            virtual status_t getCameraCharacteristics(
                    CameraMetadata *characteristics) const override;
                    CameraMetadata *characteristics) const override;
            virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
            virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
@@ -399,11 +457,12 @@ private:
            virtual status_t isSessionConfigurationSupported(
            virtual status_t isSessionConfigurationSupported(
                    const hardware::camera::device::V3_4::StreamConfiguration &configuration,
                    const hardware::camera::device::V3_4::StreamConfiguration &configuration,
                    bool *status /*out*/)
                    bool *status /*out*/)
                    const override;
                    override;


            DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
            DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
                    const std::string &id, uint16_t minorVersion,
                    const std::string &id, uint16_t minorVersion,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
                    sp<ProviderInfo> parentProvider,
                    const std::vector<std::string>& publicCameraIds, sp<InterfaceT> interface);
                    const std::vector<std::string>& publicCameraIds, sp<InterfaceT> interface);
            virtual ~DeviceInfo3();
            virtual ~DeviceInfo3();
        private:
        private:
@@ -430,11 +489,11 @@ private:
        template<class DeviceInfoT>
        template<class DeviceInfoT>
        std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &name,
        std::unique_ptr<DeviceInfo> initializeDeviceInfo(const std::string &name,
                const metadata_vendor_id_t tagId, const std::string &id,
                const metadata_vendor_id_t tagId, const std::string &id,
                uint16_t minorVersion) const;
                uint16_t minorVersion);


        // Helper for initializeDeviceInfo to use the right CameraProvider get method.
        // Helper for initializeDeviceInfo to use the right CameraProvider get method.
        template<class InterfaceT>
        template<class InterfaceT>
        sp<InterfaceT> getDeviceInterface(const std::string &name) const;
        sp<InterfaceT> startDeviceInterface(const std::string &name);


        // Parse provider instance name for type and id
        // Parse provider instance name for type and id
        static status_t parseProviderName(const std::string& name,
        static status_t parseProviderName(const std::string& name,
@@ -468,6 +527,14 @@ private:


    std::vector<sp<ProviderInfo>> mProviders;
    std::vector<sp<ProviderInfo>> mProviders;


    void addProviderToMap(
            const std::string &cameraId,
            sp<hardware::camera::provider::V2_4::ICameraProvider> provider,
            bool isTorchUsage);
    void removeCameraIdFromMap(
        std::unordered_map<std::string, sp<hardware::camera::provider::V2_4::ICameraProvider>> &map,
        const std::string &cameraId);

    static const char* deviceStatusToString(
    static const char* deviceStatusToString(
        const hardware::camera::common::V1_0::CameraDeviceStatus&);
        const hardware::camera::common::V1_0::CameraDeviceStatus&);
    static const char* torchStatusToString(
    static const char* torchStatusToString(