Android camera open 流程

在这里插入图片描述

camera open 过程涉及到 Android 架构中的三个层次:App 层,Framework 层,Runtime 层。
其中,App 层直接调用 Framework 层所封装的方法,而 Framework 层需要通过 Binder 远程调用 Runtime 中 CameraService 的函数。
@图. App to CS 函数调用逻辑

https://blog.csdn.net/qq_16775897/article/details/81537710

从 Application 连接到 CameraService

APP

mCameraManager.openCamera(currentCameraId, stateCallback, backgroundHandler);

Framework

/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
最初的入口就是 CameraManager 的 openCamera 方法,但它也是仅仅是调用了 openCameraForUid 方法,最终主要调用了 openCameraDeviceUserAsync 方法

459    /**
460     * Helper for opening a connection to a camera with the given ID.
461     *
462     * @param cameraId The unique identifier of the camera device to open
463     * @param callback The callback for the camera. Must not be null.
464     * @param executor The executor to invoke the callback with. Must not be null.
465     * @param uid      The UID of the application actually opening the camera.
466     *                 Must be USE_CALLING_UID unless the caller is a service
467     *                 that is trusted to open the device on behalf of an
468     *                 application and to forward the real UID.
469     *
470     * @throws CameraAccessException if the camera is disabled by device policy,
471     * too many camera devices are already open, or the cameraId does not match
472     * any currently available camera device.
473     *
474     * @throws SecurityException if the application does not have permission to
475     * access the camera
476     * @throws IllegalArgumentException if callback or handler is null.
477     * @return A handle to the newly-created camera device.
478     *
479     * @see #getCameraIdList
480     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
481     */
482    private CameraDevice openCameraDeviceUserAsync(String cameraId,
483            CameraDevice.StateCallback callback, Executor executor, final int uid)
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
483            CameraDevice.StateCallback callback, Executor executor, final int uid)
484            throws CameraAccessException {

//获取到目标camera的特性参数
485        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
486        CameraDevice device = null;
487
488        synchronized (mLock) {
489
490            ICameraDeviceUser cameraUser = null;

//实例化一个 CameraDeviceImpl,构造时传入了 CameraDevice.StateCallback 以及 Handler
492            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
493                    new android.hardware.camera2.impl.CameraDeviceImpl(
494                        cameraId,
495                        callback,
496                        executor,
497                        characteristics,
498                        mContext.getApplicationInfo().targetSdkVersion);

//获取 CameraDeviceCallback 实例,这是提供给远端连接到 CameraDeviceImpl 的接口
500            ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

//从 CameraManagerGlobal 中获取 CameraService 的本地接口,通过它远端调用(采用 Binder 机制)
//connectDevice 方法连接到相机设备。注意返回的 cameraUser 实际上指向的是远端
//CameraDeviceClient 的本地接口。
502            try {
503                if (supportsCamera2ApiLocked(cameraId)) {
504                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
505                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
506                    if (cameraService == null) {
507                        throw new ServiceSpecificException(
508                            ICameraService.ERROR_DISCONNECTED,
509                            "Camera service is currently unavailable");
510                    }
511                    cameraUser = cameraService.connectDevice(callbacks, cameraId,
512                            mContext.getOpPackageName(), mContext.getAttributionTag(), uid);
513                } else {
514                    // Use legacy camera implementation for HAL1 devices
515                    int id;
516                    try {
517                        id = Integer.parseInt(cameraId);
518                    } catch (NumberFormatException e) {
519                        throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
520                                + cameraId);
521                    }
522
523                    Log.i(TAG, "Using legacy camera HAL.");
524                    cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id,
525                            getDisplaySize());
526                }
527            } catch (ServiceSpecificException e) {

......
......
557            }

//将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理
559            // TODO: factor out callback to be non-nested, then move setter to constructor
560            // For now, calling setRemoteDevice will fire initial
561            // onOpened/onUnconfigured callbacks.
562            // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if
563            // cameraUser dies during setup.
564            deviceImpl.setRemoteDevice(cameraUser);
565            device = deviceImpl;
566        }
567
568        return device;
569    }

CameraDeviceImpl

/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
setRemoteDevice 
方法主要是将获取到的远端设备保存起来

283    /**
284     * Set remote device, which triggers initial onOpened/onUnconfigured callbacks
285     *
286     * <p>This function may post onDisconnected and throw CAMERA_DISCONNECTED if remoteDevice dies
287     * during setup.</p>
288     *
289     */
290    public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
291        synchronized(mInterfaceLock) {
292            // TODO: Move from decorator to direct binder-mediated exceptions
293            // If setRemoteFailure already called, do nothing
294            if (mInError) return;

//通过 ICameraDeviceUserWrapper 给远端设备实例加上一层封装
296            mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);
297
298            IBinder remoteDeviceBinder = remoteDevice.asBinder();
299            // For legacy camera device, remoteDevice is in the same process, and
300            // asBinder returns NULL.
301            if (remoteDeviceBinder != null) {
302                try {
303                    remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
304                } catch (RemoteException e) {
305                    CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);
306
307                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
308                            "The camera device has encountered a serious error");
309                }
310            }

//需要注意这个时间节点,此处触发 onOpened 与 onUnconfigured 这两个回调
//mCallOnOpened是CameraDeviceImpl类的一个成员变量
312            mDeviceExecutor.execute(mCallOnOpened);
313            mDeviceExecutor.execute(mCallOnUnconfigured);
314        }
315    }

Runtime

通过 Binder 机制,我们远端调用了 cameraService.connectDevice方法,这个方法实现在 CameraService 类中。

CameraService

/frameworks/av/services/camera/libcameraservice/CameraService.cpp

connectDevice 调用的 connectHelper 方法才真正实现了连接逻辑

1577Status CameraService::connectDevice(
1578        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1579        const String16& cameraId,
1580        const String16& clientPackageName,
1581        const std::unique_ptr<String16>& clientFeatureId,
1582        int clientUid,
1583        /*out*/
1584        sp<hardware::camera2::ICameraDeviceUser>* device) {
1585
1586    ATRACE_CALL();
1587    Status ret = Status::ok();
1588    String8 id = String8(cameraId);
1589    sp<CameraDeviceClient> client = nullptr;
1590    String16 clientPackageNameAdj = clientPackageName;
1591
1592    if (getCurrentServingCall() == BinderCallType::HWBINDER) {
1593        std::string vendorClient =
1594                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
1595        clientPackageNameAdj = String16(vendorClient.c_str());
1596    }

//调用的 connectHelper 方法才真正实现了连接逻辑,
//设定的模板类型是 ICameraDeviceCallbacks 以及 CameraDeviceClient。
1597    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
1598            /*api1CameraId*/-1,
1599            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
1600            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
1601
1602    if(!ret.isOk()) {
1603        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
1604                ret.toString8());
1605        return ret;
1606    }

//注意 client 指向的类型是 CameraDeviceClient,其实例则是最终的返回结果
1608    *device = client;
1609    return ret;
1610}

connectHelper 调用 makeClient 生成 CameraDeviceClient 实例,

template<class CALLBACK, class CLIENT>
1613Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
1614        int api1CameraId, int halVersion, const String16& clientPackageName,
1615        const std::unique_ptr<String16>& clientFeatureId, int clientUid, int clientPid,
1616        apiLevel effectiveApiLevel, bool shimUpdateOnly,
1617        /*out*/sp<CLIENT>& device) {
1618    binder::Status ret = binder::Status::ok();
1619
1620    String8 clientName8(clientPackageName);
1621
1622    int originalClientPid = 0;
1623
1624    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
1625            "Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
1626            (halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
1627            static_cast<int>(effectiveApiLevel));
1628
1629    sp<CLIENT> client = nullptr;
1630    {
1631        // Acquire mServiceLock and prevent other clients from connecting
1632        std::unique_ptr<AutoConditionLock> lock =
1633                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
1634
1635        if (lock == nullptr) {
1636            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
1637                    , clientPid);
1638            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1639                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
1640                    cameraId.string(), clientName8.string(), clientPid);
1641        }
1642
1643        // Enforce client permissions and do basic validity checks
1644        if(!(ret = validateConnectLocked(cameraId, clientName8,
1645                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
1646            return ret;
1647        }
1648
1649        // Check the shim parameters after acquiring lock, if they have already been updated and
1650        // we were doing a shim update, return immediately
1651        if (shimUpdateOnly) {
1652            auto cameraState = getCameraState(cameraId);
1653            if (cameraState != nullptr) {
1654                if (!cameraState->getShimParams().isEmpty()) return ret;
1655            }
1656        }
1657
1658        status_t err;
1659
1660        sp<BasicClient> clientTmp = nullptr;
1661        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
1662        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
1663                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
1664                /*out*/&partial)) != NO_ERROR) {
1665            switch (err) {
1666                case -ENODEV:
1667                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
1668                            "No camera device with ID \"%s\" currently available",
1669                            cameraId.string());
1670                case -EBUSY:
1671                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1672                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
1673                            cameraId.string());
1674                case -EUSERS:
1675                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1676                            "Too many cameras already open, cannot open camera \"%s\"",
1677                            cameraId.string());
1678                default:
1679                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1680                            "Unexpected error %s (%d) opening camera \"%s\"",
1681                            strerror(-err), err, cameraId.string());
1682            }
1683        }
1684
1685        if (clientTmp.get() != nullptr) {
1686            // Handle special case for API1 MediaRecorder where the existing client is returned
1687            device = static_cast<CLIENT*>(clientTmp.get());
1688            return ret;
1689        }
1690
1691        // give flashlight a chance to close devices if necessary.
1692        mFlashlight->prepareDeviceOpen(cameraId);
1693
1694        int facing = -1;
1695        int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);
1696        if (facing == -1) {
1697            ALOGE("%s: Unable to get camera device \"%s\"  facing", __FUNCTION__, cameraId.string());
1698            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1699                    "Unable to get camera device \"%s\" facing", cameraId.string());
1700        }
1701
1702        sp<BasicClient> tmp = nullptr;
1703        if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,
1704                cameraId, api1CameraId, facing,
1705                clientPid, clientUid, getpid(),
1706                halVersion, deviceVersion, effectiveApiLevel,
1707                /*out*/&tmp)).isOk()) {
1708            return ret;
1709        }
1710        client = static_cast<CLIENT*>(tmp.get());
1711
1712        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
1713                __FUNCTION__);


//这里的client就是CameraDeviceClient
1715        err = client->initialize(mCameraProviderManager, mMonitorTags);
1716        if (err != OK) {
1717            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
1718            // Errors could be from the HAL module open call or from AppOpsManager
1719            switch(err) {
1720                case BAD_VALUE:
1721                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
1722                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
1723                case -EBUSY:
1724                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
1725                            "Camera \"%s\" is already open", cameraId.string());
1726                case -EUSERS:
1727                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
1728                            "Too many cameras already open, cannot open camera \"%s\"",
1729                            cameraId.string());
1730                case PERMISSION_DENIED:
1731                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
1732                            "No permission to open camera \"%s\"", cameraId.string());
1733                case -EACCES:
1734                    return STATUS_ERROR_FMT(ERROR_DISABLED,
1735                            "Camera \"%s\" disabled by policy", cameraId.string());
1736                case -ENODEV:
1737                default:
1738                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
1739                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
1740                            strerror(-err), err);
1741            }
1742        }
1743
1744        // Update shim paremeters for legacy clients
1745        if (effectiveApiLevel == API_1) {
1746            // Assume we have always received a Client subclass for API1
1747            sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
1748            String8 rawParams = shimClient->getParameters();
1749            CameraParameters params(rawParams);
1750
1751            auto cameraState = getCameraState(cameraId);
1752            if (cameraState != nullptr) {
1753                cameraState->setShimParams(params);
1754            } else {
1755                ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",
1756                        __FUNCTION__, cameraId.string());
1757            }
1758        }
1759
1760        // Set rotate-and-crop override behavior
1761        if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
1762            client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
1763        }
1764
1765        if (shimUpdateOnly) {
1766            // If only updating legacy shim parameters, immediately disconnect client
1767            mServiceLock.unlock();
1768            client->disconnect();
1769            mServiceLock.lock();
1770        } else {
1771            // Otherwise, add client to active clients list
1772            finishConnectLocked(client, partial);
1773        }
1774    } // lock is destroyed, allow further connect calls
1775
1776    // Important: release the mutex here so the client can call back into the service from its
1777    // destructor (can be at the end of the call)
1778    device = client;
1779    return ret;
}

client->initialize(mCameraProviderManager) 初始化 CLIENT 实例。注意此处的模板类型 CLIENT 即是 CameraDeviceClient,传入的参数 mCameraProviderManager 则是与 HAL service 有关。 

makeClient 主要是根据 API 版本以及 HAL 版本来选择生成具体的 Client 实例, 一般驱动版本halVersion和设备版本deviceVersion是相同的,所以进入第一个if分支,effectiveApiLevel参数是在调用connectHelper方法时传入的,值为API_2,所以进入else分支,直接使用我们上边传进来的参数构造一个CameraDeviceClient对象,而该对象也就是我们应用进程和CameraServer进程通信的使者了,所有的工作都是由它来进行中转的。

Status CameraService::makeClient(const sp<CameraService>& cameraService,
804        const sp<IInterface>& cameraCb, const String16& packageName,
805        const std::unique_ptr<String16>& featureId, const String8& cameraId, int api1CameraId,
806        int facing, int clientPid, uid_t clientUid, int servicePid, int halVersion,
807        int deviceVersion, apiLevel effectiveApiLevel,
808        /*out*/sp<BasicClient>* client) {
809
810    if (halVersion < 0 || halVersion == deviceVersion) {
811        // Default path: HAL version is unspecified by caller, create CameraClient
812        // based on device version reported by the HAL.
813        switch(deviceVersion) {
814          case CAMERA_DEVICE_API_VERSION_1_0:
815            if (effectiveApiLevel == API_1) {  // Camera1 API route
816                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
817                *client = new CameraClient(cameraService, tmp, packageName, featureId,
818                        api1CameraId, facing, clientPid, clientUid,
819                        getpid());
820            } else { // Camera2 API route
821                ALOGW("Camera using old HAL version: %d", deviceVersion);
822                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
823                        "Camera device \"%s\" HAL version %d does not support camera2 API",
824                        cameraId.string(), deviceVersion);
825            }
826            break;
827          case CAMERA_DEVICE_API_VERSION_3_0:
828          case CAMERA_DEVICE_API_VERSION_3_1:
829          case CAMERA_DEVICE_API_VERSION_3_2:
830          case CAMERA_DEVICE_API_VERSION_3_3:
831          case CAMERA_DEVICE_API_VERSION_3_4:
832          case CAMERA_DEVICE_API_VERSION_3_5:
833          case CAMERA_DEVICE_API_VERSION_3_6:
834            if (effectiveApiLevel == API_1) { // Camera1 API route
835                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
836                *client = new Camera2Client(cameraService, tmp, packageName, featureId,
837                        cameraId, api1CameraId,
838                        facing, clientPid, clientUid,
839                        servicePid);
840            } else { // Camera2 API route
841                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
842                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
843                *client = new CameraDeviceClient(cameraService, tmp, packageName, featureId,
844                        cameraId, facing, clientPid, clientUid, servicePid);
845            }
846            break;
847          default:
848            // Should not be reachable
849            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
850            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
851                    "Camera device \"%s\" has unknown HAL version %d",
852                    cameraId.string(), deviceVersion);
853        }
854    } else {

。。。。。。
。。。。。。

873    }
874    return Status::ok();
}

最终这一 Client 就沿着前面分析下来的路径返回到 CameraDeviceImpl 实例中,被保存到 mRemoteDevice。至此,打开相机流程中,从 App 到 CameraService 的调用逻辑基本上就算走完了。

根据上面的流程追踪,我们可以描绘一个比较简单直观的连路框架图,如下。
其中黑色虚线表示下行(控制)路线,红色虚线表明上行(状态、数据)路线。

@图. App to CS 简略框架

接下来要分析的是从 CameraService 到 HAL Service 的连接过程。

从 CameraService 到 HAL Service

Android 中加入了 Treble 机制,它带来的一个巨大变化就是将原本的 CameraServer 进程分隔成 CameraServer 与 Provider service 两个进程,它们之间通过 HIDL(一个类似 Binder 的机制)进行通信。
在这种情况下,CameraServer 一端主体为 CameraService,它将会寻找现存的 Provider service,将其加入到内部的 CameraProviderManager 中进行管理,相关操作都是通过远端调用进行的。
而 Provider service 一端的主体为 CameraProvider,它在初始化时就已经连接到 libhardware 的 Camera HAL 实现层,并以 CameraModule 来进行管理,  而这两个进程的启动与初始化是在系统启动时就进行的

@图. CS 到 HAL 的连路载体

而在打开相机时,该层的完整连路会被创建出来。这一部分的主要调用逻辑如下图:

@图. CS 到 HAL 打开相机调用流程

在 CameraService::makeClient 中,实例化了一个 CameraDeviceClient。现在我们就从它的构造函数开始,继续探索打开相机的流程。 这一部分主要活动在 Runtime 层,这里分成 CameraService 与 HAL Service 两侧来分析:

CameraService 

CameraDeviceClient

/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp

CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
81        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
82        const String16& clientPackageName,
83        const std::unique_ptr<String16>& clientFeatureId,
84        const String8& cameraId,
85        int cameraFacing,
86        int clientPid,
87        uid_t clientUid,
88        int servicePid) :
89    Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
90                cameraId, /*API1 camera ID*/ -1,
91                cameraFacing, clientPid, clientUid, servicePid),
92    mInputStream(),
93    mStreamingRequestId(REQUEST_ID_NONE),
94    mRequestIdCounter(0) {
95
96    ATRACE_CALL();
97    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}

/frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

42template <typename TClientBase>
43Camera2ClientBase<TClientBase>::Camera2ClientBase(
44        const sp<CameraService>& cameraService,
45        const sp<TCamCallbacks>& remoteCallback,
46        const String16& clientPackageName,
47        const std::unique_ptr<String16>& clientFeatureId,
48        const String8& cameraId,
49        int api1CameraId,
50        int cameraFacing,
51        int clientPid,
52        uid_t clientUid,
53        int servicePid):

//模板 TClientBase,在 CameraDeviceClient 继承 Camera2ClientBase 时被指定为 CameraDeviceClientBase
54        TClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
55                cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
56        mSharedCameraCallbacks(remoteCallback),
57        mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),

//创建了一个 Camera3Device
58        mDevice(new Camera3Device(cameraId)),
59        mDeviceActive(false), mApi1CameraId(api1CameraId)
60{
61    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
62            String8(clientPackageName).string(), clientPid, clientUid);
63
64    mInitialClientPid = clientPid;
65    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
66}

再回到CameraService类的connectHelper方法,client->initialize(mCameraProviderManager)逻辑的实现,这里的client就是CameraDeviceClient了。

CameraService 在创建 CameraDeviceClient 之后,会调用它的初始化函数: 

//对外提供调用的初始化函数接口 initialize
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager) {
    return initializeImpl(manager);
}

//初始化的具体实现函数,模板 TProviderPtr 在此处即是 CameraProviderManager 类
template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
    ATRACE_CALL();
    status_t res;

//首先将父类初始化,注意此处传入了 CameraProviderManager
    res = Camera2ClientBase::initialize(providerPtr);
    if (res != OK) {
        return res;
    }

    String8 threadName;

//给成员变量 mFrameProcessor赋值
//它就是用来处理预览帧的,它继承了Thread类,相机的预览实际就是在一个无限循环当中不断的处理request来完成的。
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
    mFrameProcessor->run(threadName.string());

    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
                                      /*listener*/this,
                                      /*sendPartials*/true);

    return OK;
}

接下来再看Camera2ClientBase::initialize:

80template <typename TClientBase>
81status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
82        const String8& monitorTags) {
83    return initializeImpl(manager, monitorTags);
84}
85
//TClientBase 对应 CameraDeviceClientBase,而 TProviderPtr 对应的是 CameraProviderManager
86template <typename TClientBase>
87template <typename TProviderPtr>
88status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
89        const String8& monitorTags) {
90    ATRACE_CALL();
91    ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
92          TClientBase::mCameraIdStr.string());
93    status_t res;
94

//调用 CameraDeviceClientBase 的 startCameraOps 方法,检查 ops 的权限
95    // Verify ops permissions
96    res = TClientBase::startCameraOps();
97    if (res != OK) {
98        return res;
99    }
100
101    if (mDevice == NULL) {
102        ALOGE("%s: Camera %s: No device connected",
103                __FUNCTION__, TClientBase::mCameraIdStr.string());
104        return NO_INIT;
105    }
106

//初始化 Camera3Device 的实例,注意此处传入了 CameraProviderManager
107    res = mDevice->initialize(providerPtr, monitorTags);
108    if (res != OK) {
109        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
110                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
111        return res;
112    }
113
114    wp<NotificationListener> weakThis(this);

//在 Camera3Device 实例中设置 Notify 回调
115    res = mDevice->setNotifyCallback(weakThis);
116
117    return OK;
118}

Camera3Device

我们操作相机的所有工作在CameraServer进程都是由Camera3Device中转来和CameraDaemon进程进行通信的。

109status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
110    ATRACE_CALL();
111    Mutex::Autolock il(mInterfaceLock);
112    Mutex::Autolock l(mLock);
113
114    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
115    if (mStatus != STATUS_UNINITIALIZED) {
116        CLOGE("Already initialized!");
117        return INVALID_OPERATION;
118    }
119    if (manager == nullptr) return INVALID_OPERATION;

//在CameraDaemon进程中执行真正的camera的open过程,同时会返回一个session对象
121    sp<ICameraDeviceSession> session;
122    ATRACE_BEGIN("CameraHal::openSession");
123    status_t res = manager->openSession(mId.string(), this,
124            /*out*/ &session);
125    ATRACE_END();
126    if (res != OK) {
127        SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
128        return res;
129    }
130
131    res = manager->getCameraCharacteristics(mId.string(), &mDeviceInfo);
132    if (res != OK) {
133        SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
134        session->close();
135        return res;
136    }
137    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
138
139    std::vector<std::string> physicalCameraIds;
140    bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
141    if (isLogical) {
142        for (auto& physicalId : physicalCameraIds) {
143            res = manager->getCameraCharacteristics(
144                    physicalId, &mPhysicalDeviceInfoMap[physicalId]);
145            if (res != OK) {
146                SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
147                        physicalId.c_str(), strerror(-res), res);
148                session->close();
149                return res;
150            }
151
152            bool usePrecorrectArray =
153                    DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
154            if (usePrecorrectArray) {
155                res = mDistortionMappers[physicalId].setupStaticInfo(
156                        mPhysicalDeviceInfoMap[physicalId]);
157                if (res != OK) {
158                    SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
159                            "correction", physicalId.c_str());
160                    session->close();
161                    return res;
162                }
163            }
164
165            mZoomRatioMappers[physicalId] = ZoomRatioMapper(
166                    &mPhysicalDeviceInfoMap[physicalId],
167                    mSupportNativeZoomRatio, usePrecorrectArray);
168        }
169    }
170
171    std::shared_ptr<RequestMetadataQueue> queue;
172    auto requestQueueRet = session->getCaptureRequestMetadataQueue(
173        [&queue](const auto& descriptor) {
174            queue = std::make_shared<RequestMetadataQueue>(descriptor);
175            if (!queue->isValid() || queue->availableToWrite() <= 0) {
176                ALOGE("HAL returns empty request metadata fmq, not use it");
177                queue = nullptr;
178                // don't use the queue onwards.
179            }
180        });
181    if (!requestQueueRet.isOk()) {
182        ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
183                requestQueueRet.description().c_str());
184        return DEAD_OBJECT;
185    }
186
187    std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
188    auto resultQueueRet = session->getCaptureResultMetadataQueue(
189        [&resQueue](const auto& descriptor) {
190            resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
191            if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
192                ALOGE("HAL returns empty result metadata fmq, not use it");
193                resQueue = nullptr;
194                // Don't use the resQueue onwards.
195            }
196        });
197    if (!resultQueueRet.isOk()) {
198        ALOGE("Transaction error when getting result metadata queue from camera session: %s",
199                resultQueueRet.description().c_str());
200        return DEAD_OBJECT;
201    }
202    IF_ALOGV() {
203        session->interfaceChain([](
204            ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
205                ALOGV("Session interface chain:");
206                for (const auto& iface : interfaceChain) {
207                    ALOGV("  %s", iface.c_str());
208                }
209            });
210    }
211
212    camera_metadata_entry bufMgrMode =
213            mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
214    if (bufMgrMode.count > 0) {
215         mUseHalBufManager = (bufMgrMode.data.u8[0] ==
216            ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
217    }
218
219    camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
220    for (size_t i = 0; i < capabilities.count; i++) {
221        uint8_t capability = capabilities.data.u8[i];
222        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
223            mSupportOfflineProcessing = true;
224        }
225    }
226
227    mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
228    std::string providerType;
229    mVendorTagId = manager->getProviderTagIdLocked(mId.string());
230    mTagMonitor.initialize(mVendorTagId);
231    if (!monitorTags.isEmpty()) {
232        mTagMonitor.parseTagsToMonitor(String8(monitorTags));
233    }
234
235    // Metadata tags needs fixup for monochrome camera device version less
236    // than 3.5.
237    hardware::hidl_version maxVersion{0,0};
238    res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
239    if (res != OK) {
240        ALOGE("%s: Error in getting camera device version id: %s (%d)",
241                __FUNCTION__, strerror(-res), res);
242        return res;
243    }
244    int deviceVersion = HARDWARE_DEVICE_API_VERSION(
245            maxVersion.get_major(), maxVersion.get_minor());
246
247    bool isMonochrome = false;
248    for (size_t i = 0; i < capabilities.count; i++) {
249        uint8_t capability = capabilities.data.u8[i];
250        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
251            isMonochrome = true;
252        }
253    }
254    mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
255
256    return initializeCommonLocked();
257}

初始化函数调用了 CameraProviderManager 的 openSession 方法,开启了远端的 Session, 最后继续调用initializeCommonLocked完成初始化。

CameraProviderManager

/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

status_t CameraProviderManager::openSession(const std::string &id,
375        const sp<device::V3_2::ICameraDeviceCallback>& callback,
376        /*out*/
377        sp<device::V3_2::ICameraDeviceSession> *session) {
378
379    std::lock_guard<std::mutex> lock(mInterfaceMutex);

//首先调用 findDeviceInfoLocked,获取 HAL3 相关的 DeviceInfo3,
//这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。
//具体说就是它是在CameraService进行启动时,初始化CameraProviderManager对象的逻辑中,
//通过addProviderLocked方法生成具体的DeviceInfo对象,添加到mProviders成员变量中的
381    auto deviceInfo = findDeviceInfoLocked(id,
382            /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
383    if (deviceInfo == nullptr) return NAME_NOT_FOUND;
384
385    auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
386    sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
387    if (parentProvider == nullptr) {
388        return DEAD_OBJECT;
389    }
390    const sp<provider::V2_4::ICameraProvider> provider = parentProvider->startProviderInterface();
391    if (provider == nullptr) {
392        return DEAD_OBJECT;
393    }
394    saveRef(DeviceMode::CAMERA, id, provider);
395
396    Status status;
397    hardware::Return<void> ret;
398    auto interface = deviceInfo3->startDeviceInterface<
399            CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
400    if (interface == nullptr) {
401        return DEAD_OBJECT;
402    }

//通过远端调用 CameraDevice 的 open 方法,创建 CameraDeviceSession 实例
//并将其本地调用接口通过入参session返回
//DeviceInfo3 这个类的 mInterface 成员类型是 ICameraDevice,通过它可以调用远端 CameraDevice
404    ret = interface->open(callback, [&status, &session]
405            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
406                status = s;
407                if (status == Status::OK) {
408                    *session = cameraSession;
409                }
410            });
411    if (!ret.isOk()) {
412        removeRef(DeviceMode::CAMERA, id);
413        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
414                __FUNCTION__, id.c_str(), ret.description().c_str());
415        return DEAD_OBJECT;
416    }
417    return mapToStatusT(status);
}

HAL Service

CameraDevice

/hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp

CameraDevice 的实例实际上在初始化 HAL Service 之后就存在了。
前面说到,通过 CameraProviderManager 中的 deviceInfo 接口,调用远端 CameraDevice 实例的 open 方法:

Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
177        ICameraDevice::open_cb _hidl_cb)  {
178    Status status = initStatus();
179    sp<CameraDeviceSession> session = nullptr;
180
181    if (callback == nullptr) {
182        ALOGE("%s: cannot open camera %s. callback is null!",
183                __FUNCTION__, mCameraId.c_str());
184        _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
185        return Void();
186    }
187
188    if (status != Status::OK) {
189        // Provider will never pass initFailed device to client, so
190        // this must be a disconnected camera
191        ALOGE("%s: cannot open camera %s. camera is disconnected!",
192                __FUNCTION__, mCameraId.c_str());
193        _hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
194        return Void();
195    } else {
196        mLock.lock();
197
198        ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
199        session = mSession.promote();
200        if (session != nullptr && !session->isClosed()) {
201            ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
202            mLock.unlock();
203            _hidl_cb(Status::CAMERA_IN_USE, nullptr);
204            return Void();
205        }
206
207        /** Open HAL device */
208        status_t res;
209        camera3_device_t *device;
210
211        ATRACE_BEGIN("camera3->open");
212        res = mModule->open(mCameraId.c_str(),
213                reinterpret_cast<hw_device_t**>(&device));
214        ATRACE_END();
215
216        if (res != OK) {
217            ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
218            mLock.unlock();
219            _hidl_cb(getHidlStatus(res), nullptr);
220            return Void();
221        }
222
223        /** Cross-check device version */
224        if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
225            ALOGE("%s: Could not open camera: "
226                    "Camera device should be at least %x, reports %x instead",
227                    __FUNCTION__,
228                    CAMERA_DEVICE_API_VERSION_3_2,
229                    device->common.version);
230            device->common.close(&device->common);
231            mLock.unlock();
232            _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
233            return Void();
234        }
235
236        struct camera_info info;
237        res = mModule->getCameraInfo(mCameraIdInt, &info);
238        if (res != OK) {
239            ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
240            device->common.close(&device->common);
241            mLock.unlock();
242            _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
243            return Void();
244        }
245
246        session = createSession(
247                device, info.static_camera_characteristics, callback);
248        if (session == nullptr) {
249            ALOGE("%s: camera device session allocation failed", __FUNCTION__);
250            mLock.unlock();
251            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
252            return Void();
253        }
254        if (session->isInitFailed()) {
255            ALOGE("%s: camera device session init failed", __FUNCTION__);
256            session = nullptr;
257            mLock.unlock();
258            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
259            return Void();
260        }
261        mSession = session;
262
263        IF_ALOGV() {
264            session->getInterface()->interfaceChain([](
265                ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
266                    ALOGV("Session interface chain:");
267                    for (const auto& iface : interfaceChain) {
268                        ALOGV("  %s", iface.c_str());
269                    }
270                });
271        }
272        mLock.unlock();
273    }
274    _hidl_cb(status, session->getInterface());
275    return Void();
}

该方法的参数,第一个是callback对象,它的使用方法和我们之前讲的应用层调用openCamera时在CameraManager中传入的binder类型的callback是一样的,Server端拿到这个callback之后,就可以针对需要的节点事件回调应用层,而这里是在CameraDaemon回调CameraServer,道理是一样的。这个callback参数最终赋值给HAL层中的CameraDeviceSession类的mResultBatcher成员变量了;第二个参数是open_cb类型,从它的命名中可以看出来,它也是一个回调函数,非常方便,就像一个函数指针一样,它在CameraProviderManager一侧中像一个结构体一样传了过来,当CameraDevice类中的open执行完成后,就会将session对象作为参数回传到CameraProviderManager这一侧,我们就拿到了session,后续对camera的操作都是通过这个sesson对象来进行中转完成的。
 

mModule 是在 HAL Service 初始化时就已经配置好的,它对从 libhardware 库中加载的 Camera HAL 接口进行了一层封装。从这里往下就会一路走到 HWL 的构造流程去

211        ATRACE_BEGIN("camera3->open");
212        res = mModule->open(mCameraId.c_str(),
213                reinterpret_cast<hw_device_t**>(&device));
214        ATRACE_END();

创建 session 并让内部成员 mSession 持有,具体实现的函数为 creatSession

246        session = createSession(
247                device, info.static_camera_characteristics, callback);
248        if (session == nullptr) {
249            ALOGE("%s: camera device session allocation failed", __FUNCTION__);
250            mLock.unlock();
251            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
252            return Void();
253        }
254        if (session->isInitFailed()) {
255            ALOGE("%s: camera device session init failed", __FUNCTION__);
256            session = nullptr;
257            mLock.unlock();
258            _hidl_cb(Status::INTERNAL_ERROR, nullptr);
259            return Void();
260        }
261        mSession = session;

​​​​​​​​​​​​​​creatSession 中的实现是直接创建了一个 CameraDeviceSession。当然在其构造函数中会调用内部的初始化函数,然后会进入 HAL 接口层 HWL 的初始化流程

@图. CameraService 连接到 HAL Service 示意图

HAL Service 连接到 Camera HAL

@图. HAL Service 到 CameraHAL 的调用流程

@图. HAL Service 到 Camera HAL 的连路简图

(thanks to: https://blog.csdn.net/qq_16775897/article/details/81537710)

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值