IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Camera: SnapdragonCamera OpenCamera(三) -> 正文阅读

[移动开发]Camera: SnapdragonCamera OpenCamera(三)

? ? ? ? CameraServer与HAL的HIDL通信机制之前确实没有搞懂,在新的项目下自己找了一些资料,跟着大佬的步伐,去尽力分析每一行代码,了解相关机制。希望能在下个项目能有更加高的进步与提升吧!

主要参考资料连接:

?[Android O] Camera 服务启动流程简析

1.CamerServer 端的启动及与HAL交互机制

? ? ? ? u1s1,之前MTK Camera项目时候openCamera的机制到了CameraService这边涉及到CameraServer与Camera?HAL通信这一部分时候就被糊住了,根本没弄清楚CameraService咋么获取的HAL Camera module,然后就放弃挣扎了,想着先集成算法搞定项目然后再研究,然后就拖到高通项目上来了,下面详细去剖析一些这些获取机制。

? ? ? ? ?1.cameraServer里面实例化了CamerService,instantiate定义在了BindService中,CameraService公有继承BindService,并将CamerService加入到ServiceManager中。

?LA.UM.8.6.2/LINUX/android/frameworks/av/camera/cameraserver/main_cameraserver.cpp

#include "CameraService.h"
#include <hidl/HidlTransportSupport.h>

using namespace android;

int main(int argc __unused, char** argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    // Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
    // addition to consuming them from the Camera HAL as well.
    hardware::configureRpcThreadpool(5, /*willjoin*/ false);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    
    //CameraService实例化只有一行代码,但是过程可不是这么简单的
    CameraService::instantiate();
    ALOGI("ServiceManager: %p done instantiate", sm.get());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

?LA.UM.8.6.2/LINUX/android/frameworks/native/libs/binder/include/binder/BinderService.h

//通过类模版的方法指向CameraService
template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());

        //此时将CamerService加入到ServiceManager里面
        //CameraService被强指针使用,调用了onFirstRef接口
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }

    static void publishAndJoinThreadPool(
            bool allowIsolated = false,
            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        publish(allowIsolated, dumpFlags);
        joinThreadPool();
    }

    static void instantiate() { publish(); }

    static status_t shutdown() { return NO_ERROR; }

private:
    static void joinThreadPool() {
        sp<ProcessState> ps(ProcessState::self());
        ps->startThreadPool();
        ps->giveThreadPoolName();
        IPCThreadState::self()->joinThreadPool();
    }
};


}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_BINDER_SERVICE_H
class CameraService :
    public BinderService<CameraService>,
    public virtual ::android::hardware::BnCameraService,
    public virtual IBinder::DeathRecipient,
    public virtual CameraProviderManager::StatusListener
{
    friend class BinderService<CameraService>;
    friend class CameraClient;

? ? ? ? ?2.CameraService::onFirstRef,继承自父类RefBase,该函数在强引用时调用,有sp包装的类初始化的时候就会调用。关键是enumerateProviders和HidlCameraService->registerAsService

void CameraService::onFirstRef()
{
    ALOGI("CameraService process starting");

    BnCameraService::onFirstRef();

    // Update battery life tracking if service is restarting
    BatteryNotifier& notifier(BatteryNotifier::getInstance());
    notifier.noteResetCamera();
    notifier.noteResetFlashlight();

    status_t res = INVALID_OPERATION;

    //拿到HAL层Provider信息
    res = enumerateProviders();
    if (res == OK) {
        mInitialized = true;
    }

    //这边的俩个Policy具体的使用途径还没有搞懂
    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();
    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
    mSensorPrivacyPolicy->registerSelf();

    sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);

    //HIDL CameraService 注册AsService
    if (hcs->registerAsService() != android::OK) {
        ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
              __FUNCTION__);
    }

    // This needs to be last call in this function, so that it's as close to
    // ServiceManager::addService() as possible.
    CameraService::pingCameraServiceProxy();
    ALOGI("CameraService pinged cameraservice proxy");
}

? ? ? ? 关键是CameraProviderManager::initiallize里面的第二个形参HardwareServiceInteractionProxy,可以通过hardware::camera::provider::V2_4::ICameraProvider调用registerForNotifications和getService实现HAL层CameraProvider注册与获取的目的。

status_t CameraService::enumerateProviders() {
    status_t res;

    std::vector<std::string> deviceIds;
    {
        Mutex::Autolock l(mServiceLock);

        if (nullptr == mCameraProviderManager.get()) {
            mCameraProviderManager = new CameraProviderManager();
            
            //CameraProviderManager的初始化,initialize形参列表是有俩个参数的,另一个形参是HardwareServiceInteractionProxy的实例
            res = mCameraProviderManager->initialize(this);
            if (res != OK) {
                ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
                        __FUNCTION__, strerror(-res), res);
                return res;
            }
        }


        // Setup vendor tags before we call get_camera_info the first time
        // because HAL might need to setup static vendor keys in get_camera_info
        // TODO: maybe put this into CameraProviderManager::initialize()?
        mCameraProviderManager->setUpVendorTags();

        if (nullptr == mFlashlight.get()) {
            mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
        }

        res = mFlashlight->findFlashUnits();
        if (res != OK) {
            ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
        }

        deviceIds = mCameraProviderManager->getCameraDeviceIds();
    }

LA.UM.8.6.2/LINUX/android/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h

class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
public:

    ~CameraProviderManager();

    // Tiny proxy for the static methods in a HIDL interface that communicate with the hardware
    // service manager, to be replacable in unit tests with a fake.
    struct ServiceInteractionProxy {
        virtual bool registerForNotifications(
                const std::string &serviceName,
                const sp<hidl::manager::V1_0::IServiceNotification>
                &notification) = 0;
        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                const std::string &serviceName) = 0;
        virtual hardware::hidl_vec<hardware::hidl_string> listServices() = 0;
        virtual ~ServiceInteractionProxy() {}
    };

    // Standard use case - call into the normal generated static methods which invoke
    // the real hardware service manager
    struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
        virtual bool registerForNotifications(
                const std::string &serviceName,
                const sp<hidl::manager::V1_0::IServiceNotification>
                &notification) override {
            return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
                    serviceName, notification);
        }
        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                const std::string &serviceName) override {
            return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
        }

        virtual hardware::hidl_vec<hardware::hidl_string> listServices() override;
    };

    /**
     * Listener interface for device/torch status changes
     */
    struct StatusListener : virtual public RefBase {
        ~StatusListener() {}

        virtual void onDeviceStatusChanged(const String8 &cameraId,
                hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
        virtual void onTorchStatusChanged(const String8 &cameraId,
                hardware::camera::common::V1_0::TorchModeStatus newStatus) = 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
     * interaction proxy.
     *
     * The default proxy communicates via the hardware service manager; alternate proxies can be
     * used for testing. The lifetime of the proxy must exceed the lifetime of the manager.
     */
    //sHardwareServiceInteractionProxy静态的私有类成员变量
    status_t initialize(wp<StatusListener> listener,
            ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);


    

? ? ? ? ?CameraProviderManager的initialize里面调用HAL ICameraProvider的registerForNotifications方法(其中有一个比较困惑的地方,CameraProvider的register是CameraService在这边进行注册的?还是在HAL service.cpp里面注册的,后面在HAL层的分析阶段会单独拿出这一块只是进行一下分析),然后调用addProviderLocked

LA.UM.8.6.2/LINUX/android/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
        ServiceInteractionProxy* proxy) {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    if (proxy == nullptr) {
        ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
        return BAD_VALUE;
    }
    mListener = listener;
    mServiceProxy = proxy;
    mDeviceState = static_cast<hardware::hidl_bitfield<provider::V2_5::DeviceState>>(
        provider::V2_5::DeviceState::NORMAL);

    // Registering will trigger notifications for all already-known providers
    bool success = mServiceProxy->registerForNotifications(
        /* instance name, empty means no filter */ "",
        this);
    if (!success) {
        ALOGE("%s: Unable to register with hardware service manager for notifications "
                "about camera providers", __FUNCTION__);
        return INVALID_OPERATION;
    }


    for (const auto& instance : mServiceProxy->listServices()) {
        this->addProviderLocked(instance);
    }

    IPCThreadState::self()->flushCommands();

    return OK;
}

?addProviderLocked这边拿到的是HAL层已经注册好的Provider

status_t CameraProviderManager::addProviderLocked(const std::string& newProvider) {
    
    //判断newProviders是否已经注册
    for (const auto& providerInfo : mProviders) {
        if (providerInfo->mProviderName == newProvider) {
            ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
                    newProvider.c_str());
            return ALREADY_EXISTS;
        }
    }

    sp<provider::V2_4::ICameraProvider> interface;
    //获取底层CameraProvider接口
    interface = mServiceProxy->getService(newProvider);

    if (interface == nullptr) {
        ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
                newProvider.c_str());
        return BAD_VALUE;
    }

    //通过ProviderInfo来保存管理Provider信息
    sp<ProviderInfo> providerInfo = new ProviderInfo(newProvider, this);
    status_t res = providerInfo->initialize(interface, mDeviceState);
    if (res != OK) {
        return res;
    }

    mProviders.push_back(providerInfo);

    return OK;
}

2.HAL CameraProvider的启动及与CameraServer的交互机制

? ? ? ??HAL层CamerProvider这边有3个重点需要关注:

????????1.CameraProvider的创建时间,CameraServer时序是最靠前的,主要是需要搞清楚Provider的建立跟CameraService之前的关联关系。之前CamerService里面的CameraProviderManager的initial时候会调用一下ICameraProvider的registerForNotifications方法去注册CameraProvider导致一些关于CameraProvider注册时序的困惑。

????????我这边认为是在HAL的service.cpp的main函数里面就已经将CameraProvider注册成功了。有俩点原因,1.defaultPassthroughServiceImplementation函数是有返回值的,返回值是true;2.v我在2.4/2.5的ICameraProvider里面没有找到registerForNotifications的方法,这就很尴尬了,别问我为什么,我也不知道啊!!!苦瓜脸。

? ? ? ? 其实之前产生困惑的原因是理解有点误差,认为CameraService在跟HAL Provider联系时候要将CameraId传下去进而获得CameraDevice,所以觉得CameraService会触发CameraProvider的注册与创建,后来随着进一步的了解与学习,CameraId的传入是在Provider注册成功且CameraService获得getService()获得对应的ProviderInfo之后才传入的。

LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/default/service.cpp

#ifdef LAZY_SERVICE
const bool kLazyService = true;
#else
const bool kLazyService = false;
#endif

int main()
{
    ALOGI("CameraProvider@2.4 legacy service is starting.");
    // The camera HAL may communicate to other vendor components via
    // /dev/vndbinder
    //与vendor的driver组件相关
    android::ProcessState::initWithDriver("/dev/vndbinder");
    status_t status;

    //根据底层宏控信息创建不同的CameraProvider服务实现
    if (kLazyService) {
        status = defaultLazyPassthroughServiceImplementation<ICameraProvider>("legacy/0",
                                                                              /*maxThreads*/ 6);
    } else {
        status = defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0",
                                                                          /*maxThreads*/ 6);
    }
    return status;
}

LA.UM.8.6.2/LINUX/android/system/libhidl/transport/include/hidl/LegacySupport.h

namespace details {

//这边的类模版对应的Interface、Func分别为ICameraProvider、ICameraProviderCallback
template <class Interface, typename Func>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
    Func registerServiceCb, const std::string& name = "default") {
    sp<Interface> service = Interface::getService(name, true /* getStub */);

    if (service == nullptr) {
        ALOGE("Could not get passthrough implementation for %s/%s.",
            Interface::descriptor, name.c_str());
        return EXIT_FAILURE;
    }

    LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
            Interface::descriptor, name.c_str());

    status_t status = registerServiceCb(service, name);

    if (status == OK) {
        ALOGI("Registration complete for %s/%s.",
            Interface::descriptor, name.c_str());
    } else {
        ALOGE("Could not register service %s/%s (%d).",
            Interface::descriptor, name.c_str(), status);
    }

    return status;
}
}  // namespace details



//passthrough CameraProvider的创建过程
/**
 * Registers passthrough service implementation.
 */
template <class Interface>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
    const std::string& name = "default") {

    //Interface为Service.cpp传入的类模版ICameraProvider
    return details::registerPassthroughServiceImplementation<Interface>(
        [](const sp<Interface>& service, const std::string& name) {

            
            return service->registerAsService(name);
        },
        name);
}

/**
 * Creates default passthrough service implementation. This method never returns.
 *
 * Return value is exit status.
 */
template <class Interface>
__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
    const std::string& name, size_t maxThreads = 1) {

    //配置 RPC 线程池
    configureRpcThreadpool(maxThreads, true);

    //name:Service.cpp里面传入的legacy/0
    status_t result = registerPassthroughServiceImplementation<Interface>(name);

    if (result != OK) {
        return result;
    }

    //加入到线程池中
    joinRpcThreadpool();
    return UNKNOWN_ERROR;
}

?

????????2.CamerProvider功能熟悉与常用接口熟悉;ICameraProvider.hal和ICameraProviderCallback.hal

LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/ICameraProvider.hal

/**
 * Camera provider HAL, which enumerates the available individual camera devices
 * known to the provider, and provides updates about changes to device status,
 * such as connection, disconnection, or torch mode enable/disable.
 *
 * The provider is responsible for generating a list of camera device service
 * names that can then be opened via the hardware service manager.
 *
 * Multiple camera provider HALs may be present in a single system.
 * For discovery, the service names, and process names, must be of the form
 * "android.hardware.camera.provider@<major>.<minor>/<type>/<instance>"
 * where
 *   - <major>/<minor> is the provider HAL HIDL version,
 *   - <type> is the type of devices this provider knows about, such as
 *     "internal", "legacy", "external", "remote" etc. The camera framework
 *     must not differentiate or chage its behavior based on the specific type.
 *   - <instance> is a non-negative integer starting from 0 to disambiguate
 *     between multiple HALs of the same type.
 *
 * The "legacy" type is only used for passthrough legacy HAL mode, and must
 * not be used by a standalone binderized HAL.
 *
 * The device instance names enumerated by the provider in getCameraIdList() or
 * ICameraProviderCallback::cameraDeviceStatusChange() must be of the form
 * "device@<major>.<minor>/<type>/<id>" where
 * <major>/<minor> is the HIDL version of the interface. <id> is either a small
 * incrementing integer for "internal" device types, with 0 being the main
 * back-facing camera and 1 being the main front-facing camera, if they exist.
 * Or, for external devices, a unique serial number (if possible) that can be
 * used to identify the device reliably when it is disconnected and reconnected.
 *
 * Multiple providers must not enumerate the same device ID.
 */
interface ICameraProvider {
    ...
}

setCallback(check HAL provider status)

    /**
     * setCallback:
     *
     * Provide a callback interface to the HAL provider to inform framework of
     * asynchronous camera events. The framework must call this function once
     * during camera service startup, before any other calls to the provider
     * (note that in case the camera service restarts, this method must be
     * invoked again during its startup).
     *
     * @param callback
     *     A non-null callback interface to invoke when camera events occur.
     * @return status
     *     Status code for the operation, one of:
     *     OK:
     *         On success
     *     INTERNAL_ERROR:
     *         An unexpected internal error occurred while setting the callbacks
     *     ILLEGAL_ARGUMENT:
     *         The callback argument is invalid (for example, null).
     *
     */
    setCallback(ICameraProviderCallback callback) generates (Status status);

getVendorTags(check all tags be supported by current provider)

    /**
     * getVendorTags:
     *
     * Retrieve all vendor tags supported by devices discoverable through this
     * provider. The tags are grouped into sections.
     *
     * @return status
     *     Status code for the operation, one of:
     *     OK:
     *         On success
     *     INTERNAL_ERROR:
     *         An unexpected internal error occurred while setting the callbacks
     * @return sections
     *     The supported vendor tag sections; empty if there are no supported
     *     vendor tags, or status is not OK.
     *
     */
    getVendorTags() generates (Status status, vec<VendorTagSection> sections);

getCameraIdList(can get all internal camera devices by current provider but can not get external camera devices)

? ? ? ? 这边涉及到internal/external camera devices,这俩个对应的是不同的provider,分别由service.cpp和external-service.cpp来注册创建,代入手机项目中,internal camera devices对应的是前后摄,external-services是虚化双摄以及深度相机等。

    /**
     * getCameraIdList:
     *
     * Returns the list of internal camera device interfaces known to this
     * camera provider. These devices can then be accessed via the hardware
     * service manager.
     *
     * External camera devices (camera facing EXTERNAL) must be reported through
     * the device status change callback, not in this list. Only devices with
     * facing BACK or FRONT must be listed here.
     *
     * @return status Status code for the operation, one of:
     *     OK:
     *         On a succesful generation of camera ID list
     *     INTERNAL_ERROR:
     *         A camera ID list cannot be created. This may be due to
     *         a failure to initialize the camera subsystem, for example.
     * @return cameraDeviceServiceNames The vector of internal camera device
     *     names known to this provider.
     */
    getCameraIdList()
            generates (Status status, vec<string> cameraDeviceNames);

isSetTorchModeSupported()

    /**
     * isSetTorchModeSupported:
     *
     * Returns if the camera devices known to this camera provider support
     * setTorchMode API or not. If the provider does not support setTorchMode
     * API, calling to setTorchMode will return METHOD_NOT_SUPPORTED.
     *
     * Note that not every camera device has a flash unit, so even this API
     * returns true, setTorchMode call might still fail due to the camera device
     * does not have a flash unit. In such case, the returned status will be
     * OPERATION_NOT_SUPPORTED.
     *
     * @return status Status code for the operation, one of:
     *     OK:
     *         On a succesful call
     *     INTERNAL_ERROR:
     *         Torch API support cannot be queried. This may be due to
     *         a failure to initialize the camera subsystem, for example.
     * @return support Whether the camera devices known to this provider
     *     supports setTorchMode API or not. Devices launched with SDK
     *     level 29 or higher must return true.
     *
     */
    isSetTorchModeSupported() generates (Status status, bool support);

getCameraDeviceInterface_V1_x/V3_x()等。

    /**
     * getCameraDeviceInterface_VN_x:
     *
     * Return a android.hardware.camera.device@N.x/ICameraDevice interface for
     * the requested device name. This does not power on the camera device, but
     * simply acquires the interface for querying the device static information,
     * or to additionally open the device for active use.
     *
     * A separate method is required for each major revision of the camera device
     * HAL interface, since they are not compatible with each other.
     *
     * Valid device names for this provider can be obtained via either
     * getCameraIdList(), or via availability callbacks from
     * ICameraProviderCallback::cameraDeviceStatusChange().
     *
     * The returned interface must be of the highest defined minor version for
     * the major version; it's the responsibility of the HAL client to ensure
     * they do not use methods/etc that are not valid for the actual minor
     * version of the device.
     *
     * @param cameraDeviceName the name of the device to get an interface to.
     * @return status Status code for the operation, one of:
     *     OK:
     *         On a succesful generation of camera ID list
     *     ILLEGAL_ARGUMENT:
     *         This device name is unknown, or has been disconnected
     *     OPERATION_NOT_SUPPORTED:
     *         The specified device does not support this major version of the
     *         HAL interface.
     *     INTERNAL_ERROR:
     *         A camera interface cannot be returned due to an unexpected
     *         internal error.
     * @return device The inteface to this camera device, or null in case of
     *     error.
     */
    getCameraDeviceInterface_V1_x(string cameraDeviceName) generates
            (Status status,
             android.hardware.camera.device@1.0::ICameraDevice device);
    getCameraDeviceInterface_V3_x(string cameraDeviceName) generates
            (Status status,
             android.hardware.camera.device@3.2::ICameraDevice device);

?LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/ICameraProviderCallback.hal

package android.hardware.camera.provider@2.4;

import android.hardware.camera.common@1.0::types;

/**
 * Callback functions for a camera provider HAL to use to inform the camera
 * service of changes to the camera subsystem.
 */
interface ICameraProviderCallback {

    /**
     * cameraDeviceStatusChange:
     *
     * Callback to the camera service to indicate that the state of a specific
     * camera device has changed.
     *
     * On camera service startup, when ICameraProvider::setCallback is invoked,
     * the camera service must assume that all internal camera devices are in
     * the CAMERA_DEVICE_STATUS_PRESENT state.
     *
     * The provider must call this method to inform the camera service of any
     * initially NOT_PRESENT devices, and of any external camera devices that
     * are already present, as soon as the callbacks are available through
     * setCallback.
     *
     * @param cameraDeviceServiceName The name of the camera device that has a
     *     new status.
     * @param newStatus The new status that device is in.
     *
     */
    cameraDeviceStatusChange(string cameraDeviceName,
            CameraDeviceStatus newStatus);

    /**
     * torchModeStatusChange:
     *
     * Callback to the camera service to indicate that the state of the torch
     * mode of the flash unit associated with a specific camera device has
     * changed. At provider registration time, the camera service must assume
     * the torch modes are in the TORCH_MODE_STATUS_AVAILABLE_OFF state if
     * android.flash.info.available is reported as true via the
     * ICameraDevice::getCameraCharacteristics call.
     *
     * @param cameraDeviceServiceName The name of the camera device that has a
     *     new status.
     * @param newStatus The new status that device is in.
     *
     */
    torchModeStatusChange(string cameraDeviceName,
            TorchModeStatus newStatus);

};

????????3.CamerProvider初始化过程,以及咋么传递加载HAL层关键数据,进而获得CameraDevice的。初始化的主要流程是CameraProvider::HIDL_FETCH_ICameraProvider -> getProviderImpl<LegacyCameraProviderImpl_2_4>(以LegacyCameraProviderImpl为例),然后new?LegacyCameraProviderImpl_2_4调用了LegacyCameraProviderImpl_2_4::initialize(),主要的流程与CameraDevice的交互都在这边了。

LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/default/CameraProvider_2_4.h

template<typename IMPL>
struct CameraProvider : public ICameraProvider {
    CameraProvider() : impl() {}
    ~CameraProvider() {}

    // Caller must use this method to check if CameraProvider ctor failed
    bool isInitFailed() { return impl.isInitFailed(); }

    // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override {
        return impl.setCallback(callback);
    }

    Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override {
        return impl.getVendorTags(_hidl_cb);
    }

    Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override {
        return impl.getCameraIdList(_hidl_cb);
    }

    Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override {
        return impl.isSetTorchModeSupported(_hidl_cb);
    }

    Return<void> getCameraDeviceInterface_V1_x(
            const hidl_string& cameraDeviceName,
            getCameraDeviceInterface_V1_x_cb _hidl_cb) override {
        return impl.getCameraDeviceInterface_V1_x(cameraDeviceName, _hidl_cb);
    }

    Return<void> getCameraDeviceInterface_V3_x(
            const hidl_string& cameraDeviceName,
            getCameraDeviceInterface_V3_x_cb _hidl_cb) override {
        return impl.getCameraDeviceInterface_V3_x(cameraDeviceName, _hidl_cb);
    }

private:
    IMPL impl;
};

?LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/default/CameraProvider_2_4.cpp

#include "CameraProvider_2_4.h"
#include "LegacyCameraProviderImpl_2_4.h"
#include "ExternalCameraProviderImpl_2_4.h"

const char *kLegacyProviderName = "legacy/0";
const char *kExternalProviderName = "external/0";

namespace android {
namespace hardware {
namespace camera {
namespace provider {
namespace V2_4 {
namespace implementation {

using android::hardware::camera::provider::V2_4::ICameraProvider;

extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name);

template<typename IMPL>
CameraProvider<IMPL>* getProviderImpl() {
    CameraProvider<IMPL> *provider = new CameraProvider<IMPL>();
    if (provider == nullptr) {
        ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
        return nullptr;
    }
    if (provider->isInitFailed()) {
        ALOGE("%s: camera provider init failed!", __FUNCTION__);
        delete provider;
        return nullptr;
    }
    return provider;
}

ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
    using namespace android::hardware::camera::provider::V2_4::implementation;
    ICameraProvider* provider = nullptr;
    if (strcmp(name, kLegacyProviderName) == 0) {
        provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();
    } else if (strcmp(name, kExternalProviderName) == 0) {
        provider = getProviderImpl<ExternalCameraProviderImpl_2_4>();
    } else {
        ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
    }

    return provider;
}

}  // namespace implementation
}  // namespace V2_4
}  // namespace provider
}  // namespace camera
}  // namespace hardware
}  // namespace android

?LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp

? ? ? ? 引用文章开头大佬对此次initialize的分析,连接:LegacyCmaeraProviderImpl initialize接口操作

整个函数实现比较冗长,只贴出我们需要关注的部分分析。

第 1~7 行:需要注意 rawModule 这个指针指向的结构,通过 hw_get_module 函数获取到它的实例(从相应的 Camera HAL 动态库中加载得到)。实际上这个结构就是连接到 HAL 层的关键点,通过它就可以调用到 HAL 中的一些函数。
(关于 hw_get_module,我以前分析过 Android N 上相关的逻辑,在 O 上其实没有很大改动,如果要详细了解可以去看看那篇文章)
第 9~15 行:基于 rawModule 创建 CameraModule 实例并初始化。之后都是通过 mModule 来对 HAL 进行操作的。(其实 CameraModule 是对于 camera_module_t 的一层封装,诸如 init、open 这样的操作,实际上都是通过调用 camera_module_t 结构中函数指针指向的 HAL 层的具体实现函数来完成的)
执行完这个函数,CameraProvider 也就随之初始化完成了。

LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :
        camera_module_callbacks_t({sCameraDeviceStatusChange,
                                   sTorchModeStatusChange}) {
    mInitFailed = initialize();
}

LegacyCameraProviderImpl_2_4::~LegacyCameraProviderImpl_2_4() {}

bool LegacyCameraProviderImpl_2_4::initialize() {
    camera_module_t *rawModule;
    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
            (const hw_module_t **)&rawModule);
    if (err < 0) {
        ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
        return true;
    }

    mModule = new CameraModule(rawModule);
    err = mModule->init();
    if (err != OK) {
        ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }
    ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());

    // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
    if (!setUpVendorTags()) {
        ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
    }

    // Setup callback now because we are going to try openLegacy next
    err = mModule->setCallbacks(this);
    if (err != OK) {
        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }

    mPreferredHal3MinorVersion =
        property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
    ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
    switch(mPreferredHal3MinorVersion) {
        case 2:
        case 3:
            // OK
            break;
        default:
            ALOGW("Unknown minor camera device HAL version %d in property "
                    "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
                    mPreferredHal3MinorVersion);
            mPreferredHal3MinorVersion = 3;
    }

    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        uint32_t device_version;
        auto rc = mModule->getCameraDeviceVersion(i, &device_version);
        if (rc != NO_ERROR) {
            ALOGE("%s: Camera device version query failed!", __func__);
            mModule.clear();
            return true;
        }

        if (checkCameraVersion(i, device_version) != OK) {
            ALOGE("%s: Camera version check failed!", __func__);
            mModule.clear();
            return true;
        }

        char cameraId[kMaxCameraIdLen];
        snprintf(cameraId, sizeof(cameraId), "%d", i);
        std::string cameraIdStr(cameraId);
        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;

        addDeviceNames(i);
    }

    return false; // mInitFailed
}

LA.UM.8.6.2/LINUX/android/hardware/interfaces/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.h?

/**
 * The implementation of legacy wrapper CameraProvider 2.4, separated
 * from the HIDL interface layer to allow for implementation reuse by later
 * provider versions.
 *
 * This implementation supports cameras implemented via the legacy libhardware
 * camera HAL definitions.
 */
struct LegacyCameraProviderImpl_2_4 : public camera_module_callbacks_t {
    LegacyCameraProviderImpl_2_4();
    ~LegacyCameraProviderImpl_2_4();

    // Caller must use this method to check if CameraProvider ctor failed
    bool isInitFailed() { return mInitFailed; }

    // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback);
    Return<void> getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb);
    Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
    Return<void> isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb);
    Return<void> getCameraDeviceInterface_V1_x(
            const hidl_string& cameraDeviceName,
            ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb);
    Return<void> getCameraDeviceInterface_V3_x(
            const hidl_string& cameraDeviceName,
            ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb);

protected:
    Mutex mCbLock;
    sp<ICameraProviderCallback> mCallbacks = nullptr;

    sp<CameraModule> mModule;

    int mNumberOfLegacyCameras;
    std::map<std::string, camera_device_status_t> mCameraStatusMap; // camera id -> status
    std::map<std::string, bool> mOpenLegacySupported; // camera id -> open_legacy HAL1.0 supported
    SortedVector<std::string> mCameraIds; // the "0"/"1" legacy camera Ids
    // (cameraId string, hidl device name) pairs
    SortedVector<std::pair<std::string, std::string>> mCameraDeviceNames;

    int mPreferredHal3MinorVersion;

    // Must be queried before using any APIs.
    // APIs will only work when this returns true
    bool mInitFailed;
    bool initialize();

    hidl_vec<VendorTagSection> mVendorTagSections;
    bool setUpVendorTags();
    int checkCameraVersion(int id, uint32_t device_version);

    // create HIDL device name from camera ID and legacy device version
    std::string getHidlDeviceName(std::string cameraId, int deviceVersion);

    // extract legacy camera ID/device version from a HIDL device name
    static std::string getLegacyCameraId(const hidl_string& deviceName);

    // convert conventional HAL status to HIDL Status
    static Status getHidlStatus(int);

    // static callback forwarding methods
    static void sCameraDeviceStatusChange(
        const struct camera_module_callbacks* callbacks,
        int camera_id,
        int new_status);
    static void sTorchModeStatusChange(
        const struct camera_module_callbacks* callbacks,
        const char* camera_id,
        int new_status);

    void addDeviceNames(int camera_id, CameraDeviceStatus status = CameraDeviceStatus::PRESENT,
                        bool cam_new = false);
    void removeDeviceNames(int camera_id);

};

小结:

? ? ? ? u1s1,CameraService和HAL CameraProvider交互的这一部分真的很让人头大,最近项目上问题比较多,就每天整理一小部分,拖了几天才解决。这仅仅是跟着大佬的分析把这一部分涉及到的代码过了一下,梳理了一下自己之前的思路,纠正了一些理解不到位的点。现在对这一部分框架的状态仅仅是Touch到了,远远没达到熟悉掌握的地步,后续会不断结合项目中遇到的问题进一步巩固这庞大冗余的架构体系。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 22:45:57  更:2021-07-30 22:46:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 1:38:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码