Android14 Camera-API2 openCamera执行过程

3 阅读18分钟

这篇文章主要是介绍Camera2中openCamera函数的执行过程, 下面开始一起看源码吧!

在开发中我们要使用Camera需要先获取一个CameraManager,获取到CameraManager 通过openCamera函数打开Camera frameworks/base/core/java/android/hardware/camera2/CameraManager.java

private static final int USE_CALLING_UID = -1;
public void openCamera(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
        throws CameraAccessException {

    openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
            USE_CALLING_UID);
}

public void openCameraForUid(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
        int clientUid) throws CameraAccessException {
    openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0,
            shouldOverrideToPortrait(mContext));
}

public void openCameraForUid(@NonNull String cameraId,
        @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
        int clientUid, int oomScoreOffset, boolean overrideToPortrait)
        throws CameraAccessException {

    // 省略无关细节代码 .....
    openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset,
            overrideToPortrait);
}

private CameraDevice openCameraDeviceUserAsync(String cameraId,
        CameraDevice.StateCallback callback, Executor executor, final int uid,
        final int oomScoreOffset, boolean overrideToPortrait) throws CameraAccessException {
    // 获取指定Camera Id 的参数
    CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
    CameraDevice device = null;
    // 获取所有物理Camera设备的参数
    Map<String, CameraCharacteristics> physicalIdsToChars =
            getPhysicalIdToCharsMap(characteristics);
    synchronized (mLock) {

        ICameraDeviceUser cameraUser = null;
        // 创建CameraDeviceImpl 
        android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                new android.hardware.camera2.impl.CameraDeviceImpl(
                    cameraId,
                    callback,
                    executor,
                    characteristics,
                    physicalIdsToChars,
                    mContext.getApplicationInfo().targetSdkVersion,
                    mContext);

        ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

        try {
            // 获取CameraService
            ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
            if (cameraService == null) {
                throw new ServiceSpecificException(
                    ICameraService.ERROR_DISCONNECTED,
                    "Camera service is currently unavailable");
            }
            // 连接Devices
            cameraUser = cameraService.connectDevice(callbacks, cameraId,
                mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
                oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
                overrideToPortrait);
        } catch (ServiceSpecificException e) {
             // 省略异常处理代码.....
            // 这段异常处理的代码很大一部分都异常都会导致onDisconnected函数回调
        } catch (RemoteException e) {
            // 省略异常处理代码.....
        }

        deviceImpl.setRemoteDevice(cameraUser);
        device = deviceImpl;
    }

    return device;
}

上面的代码是使用openCamera函数Java部分启动过程,看到这里有几个问题,

  1. 为什么在调用openCamera函数的时候一定要在有handler的线程中调用?
  2. openCamera函数成功调用后如何调用Callback ?

问题1:为什么在调用openCamera函数的时候一定要在有handler的线程中调用? 在openCamera 函数中有这样一段代码CameraDeviceImpl.checkAndWrapHandler(handler) 下面看一下这个实现就会很清楚原因了

public static Executor checkAndWrapHandler(Handler handler) {
    return new CameraHandlerExecutor(checkHandler(handler));
}

static Handler checkHandler(Handler handler) {
    if (handler == null) {
        Looper looper = Looper.myLooper();
        if (looper == null) {
            throw new IllegalArgumentException(
                "No handler given, and current thread has no looper!");
        }
        handler = new Handler(looper);
    }
    return handler;
}

其实就是判断openCamera函数调用时候传入的handler是否为null,如果为null 就获取一下当前线程的looper, 如果当前线程没有looper ,不满足条件,抛异常,否则就正常执行

问题2:openCamera函数成功调用后如何调用Callback ? 首先要看一下CameraDeviceImpl.java的构造函数

public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
                    CameraCharacteristics characteristics, int appTargetSdkVersion) {
    if (cameraId == null || callback == null || executor == null || characteristics == null) {
        throw new IllegalArgumentException("Null argument given");
    }
    mCameraId = cameraId;
    mDeviceCallback = callback; // 回调
    mDeviceExecutor = executor; // 执行任务
    mCharacteristics = characteristics;
    mAppTargetSdkVersion = appTargetSdkVersion; // 

     // 省略无关细节代码 .....
}

从构造函数中可以看到有mDeviceCallbackmDeviceExecutor回调和任务执行线程, 下面看一下deviceImpl.setRemoteDevice(cameraUser); 执行

public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
    synchronized(mInterfaceLock) {
        // TODO: Move from decorator to direct binder-mediated exceptions
        // If setRemoteFailure already called, do nothing
        if (mInError) return;

        mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);

        IBinder remoteDeviceBinder = remoteDevice.asBinder();
        // For legacy camera device, remoteDevice is in the same process, and
        // asBinder returns NULL.
        if (remoteDeviceBinder != null) {
            try {
                // 设置binder death 监听, 如果发生错误会回调 call back onDisconnected
                remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
            } catch (RemoteException e) {
                CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);

                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                        "The camera device has encountered a serious error");
            }
        }
        // 执行打开成功回调
        mDeviceExecutor.execute(mCallOnOpened);
        mDeviceExecutor.execute(mCallOnUnconfigured);

        mRemoteDeviceInit = true;
    }
}


private final Runnable mCallOnOpened = new Runnable() {
    @Override
    public void run() {
        StateCallbackKK sessionCallback = null;
        synchronized(mInterfaceLock) {
            // 检测camera 是否关闭
            if (mRemoteDevice == null) return; // Camera already closed
            sessionCallback = mSessionStateCallback;
        }
        if (sessionCallback != null) {
            sessionCallback.onOpened(CameraDeviceImpl.this);
        }
        mDeviceCallback.onOpened(CameraDeviceImpl.this);
    }
};

private final Runnable mCallOnDisconnected = new Runnable() {
    @Override
    public void run() {
        StateCallbackKK sessionCallback = null;
        synchronized(mInterfaceLock) {
            // 检测camera 是否关闭
            if (mRemoteDevice == null) return; // Camera already closed
            sessionCallback = mSessionStateCallback;
        }
        if (sessionCallback != null) {
            sessionCallback.onDisconnected(CameraDeviceImpl.this);
        }
        mDeviceCallback.onDisconnected(CameraDeviceImpl.this);
    }
};

从上面代码可以很清楚看到,设置了binder death 监听, 如果发生错误会回调 callback的onDisconnected函数, 如果Camera 已经关闭将不会回调, 当一切都正常执行后会回调打开成功回调。

App层打开逻辑比较好理解,看一下App层是怎么获取到CameraService并且打开Camera的,在上面代码可以清晰看到

// Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

可以看到 CameraManagerGlobal是个单例,在该单例中获取CameraService,进一步查看代码

public ICameraService getCameraService() {
synchronized(mLock) {
    connectCameraServiceLocked();
    if (mCameraService == null && !sCameraServiceDisabled) {
        Log.e(TAG, "Camera service is unavailable");
    }
    return mCameraService;
}
}

// 这个字符串是不是很熟悉, 在camera 开机初始化的时候见到过
private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";

private void connectCameraServiceLocked() {
    // Only reconnect if necessary
    if (mCameraService != null || sCameraServiceDisabled) return;

    Log.i(TAG, "Connecting to camera service");

    // 获取Camera 服务
    IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
    if (cameraServiceBinder == null) {
        // Camera service is now down, leave mCameraService as null
        return;
    }
    try {
        // 设置Camera 服务的bind death 监听
        cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
    } catch (RemoteException e) {
        // Camera service is now down, leave mCameraService as null
        return;
    }

    ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
    // 省略无关代码....
    try {
        // 省略无关代码....
        // 赋值mCameraService
        mCameraService = cameraService;
    } catch(ServiceSpecificException e) {
        // Unexpected failure
        throw new IllegalStateException("Failed to register a camera service listener", e);
    } catch (RemoteException e) {
        // Camera service is now down, leave mCameraService as null
    }

    // 省略无关代码....
}

上面代码通过binder通信,ServiceManager获取到ICameraService

下面到CameraService,下面看一下调用cameraService.connectDevice(callbacks, cameraId,mContext.getOpPackageName(), uid); 这个连接函数后在CameraService 中都做了什么。

CameraService在framework中的位置:/frameworks/av/services/camera/libcameraservice/CameraService.cpp 看一下在CameraService.cpp的实现:

Status CameraService::connectDevice(
        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        const std::optional<String16>& clientFeatureId,
        int clientUid, int oomScoreOffset, int targetSdkVersion,
        bool overrideToPortrait,
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    String16 clientPackageNameAdj = clientPackageName;
    int callingPid = CameraThreadState::getCallingPid();
     // 省略无关细节代码 .....
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient,clientFeatureId,
            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
            targetSdkVersion, overrideToPortrait, /*forceSlowJpegMode*/false,
            /*out*/client);

     // 省略无关细节代码 .....

    *device = client;
    // 省略无关细节代码 .....
    return ret;
}

进入CameraService::connectHelper 看一下具体实现

// 3 second busy timeout when other clients are connecting
static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000;

template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
        bool overrideToPortrait, bool forceSlowJpegMode,
        /*out*/sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();
    // 省略无关代码.....
    String8 clientName8(clientPackageName);

    int originalClientPid = 0;
    // 省略无关代码.....
    nsecs_t openTimeNs = systemTime();

    sp<CLIENT> client = nullptr;
    int facing = -1;
    int orientation = 0;

    {
        // Acquire mServiceLock and prevent other clients from connecting
        // 获取一个锁
        std::unique_ptr<AutoConditionLock> lock =
                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);

        if (lock == nullptr) {
            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
                    , clientPid);
            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
                    cameraId.string(), clientName8.string(), clientPid);
        }

        // Enforce client permissions and do basic validity checks
        // 检查权限
        if(!(ret = validateConnectLocked(cameraId, clientName8,
                /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
            return ret;
        }

        // 省略无关代码.....
        status_t err;

        sp<BasicClient> clientTmp = nullptr;
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
        // 检查当前启动Camera 请求的优先级
        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
                IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, systemNativeClient,
                /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
            switch (err) {
                case -ENODEV:
                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                            "No camera device with ID \"%s\" currently available",
                            cameraId.string());
                case -EBUSY:
                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
                            cameraId.string());
                case -EUSERS:
                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                            "Too many cameras already open, cannot open camera \"%s\"",
                            cameraId.string());
                default:
                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                            "Unexpected error %s (%d) opening camera \"%s\"",
                            strerror(-err), err, cameraId.string());
            }
        }

        // 省略无关代码.....
        // 创建Camera连接
        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, facing, orientation,
                clientPid, clientUid, getpid(),
                deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                overrideToPortrait, forceSlowJpegMode,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());

        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);

        String8 monitorTags = isClientWatched(client.get()) ? mMonitorTags : String8("");
        // 初始化当前Camera 连接
        err = client->initialize(mCameraProviderManager, monitorTags);
        if (err != OK) {
            ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
            // Errors could be from the HAL module open call or from AppOpsManager
            switch(err) {
                case BAD_VALUE:
                    return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
                            "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
                case -EBUSY:
                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                            "Camera \"%s\" is already open", cameraId.string());
                case -EUSERS:
                    return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
                            "Too many cameras already open, cannot open camera \"%s\"",
                            cameraId.string());
                case PERMISSION_DENIED:
                    return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                            "No permission to open camera \"%s\"", cameraId.string());
                case -EACCES:
                    return STATUS_ERROR_FMT(ERROR_DISABLED,
                            "Camera \"%s\" disabled by policy", cameraId.string());
                case -ENODEV:
                default:
                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                            "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
                            strerror(-err), err);
            }
        }

        // 省略无关代码.....
        if (shimUpdateOnly) {
            // If only updating legacy shim parameters, immediately disconnect client
            mServiceLock.unlock();
            client->disconnect();
            mServiceLock.lock();
        } else {
            // Otherwise, add client to active clients list
            // 连接创建完成
            finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient);
        }

        client->setImageDumpMask(mImageDumpMask);
        client->setStreamUseCaseOverrides(mStreamUseCaseOverrides);
        client->setZoomOverride(mZoomOverrideValue);
    } // lock is destroyed, allow further connect calls

    // 省略无关代码.....

    return ret;
}

简单介绍一下handleEvictionsLocked函数, 这个函数主要检测当前要打开的连接和已经打开的连接是否有冲突,产生冲突将终止,否则继续执行,这里涉及到App打开Camera优先级问题,这里不详细介绍,对这块感兴趣可以阅读《Android14 Camera-启动时Camera 的优先级》这篇文章。

上面handleEvictionsLocked这个函数执行完返回的不是异常code将会进入创建makeClient 函数

Status CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, bool systemNativeClient,
        const std::optional<String16>& featureId,  const String8& cameraId,
        int api1CameraId, int facing, int sensorOrientation, int clientPid, uid_t clientUid,
        int servicePid, std::pair<int, IPCTransport> deviceVersionAndTransport,
        apiLevel effectiveApiLevel, bool overrideForPerfClass, bool overrideToPortrait,
        bool forceSlowJpegMode, /*out*/sp<BasicClient>* client) {
    // For HIDL devices
    if (deviceVersionAndTransport.second == IPCTransport::HIDL) {
        // Create CameraClient based on device version reported by the HAL.
        int deviceVersion = deviceVersionAndTransport.first;
        switch(deviceVersion) {
            case CAMERA_DEVICE_API_VERSION_1_0:
                ALOGE("Camera using old HAL version: %d", deviceVersion);
                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                        "Camera device \"%s\" HAL version %d no longer supported",
                        cameraId.string(), deviceVersion);
                break;
            case CAMERA_DEVICE_API_VERSION_3_0:
            case CAMERA_DEVICE_API_VERSION_3_1:
            case CAMERA_DEVICE_API_VERSION_3_2:
            case CAMERA_DEVICE_API_VERSION_3_3:
            case CAMERA_DEVICE_API_VERSION_3_4:
            case CAMERA_DEVICE_API_VERSION_3_5:
            case CAMERA_DEVICE_API_VERSION_3_6:
            case CAMERA_DEVICE_API_VERSION_3_7:
                break;
            default:
                // Should not be reachable
                ALOGE("Unknown camera device HAL version: %d", deviceVersion);
                return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                        "Camera device \"%s\" has unknown HAL version %d",
                        cameraId.string(), deviceVersion);
        }
    }
    // 根据effectiveApiLevel 判断创建哪个API
    if (effectiveApiLevel == API_1) { // Camera1 API route
        sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
        *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
                packageName, featureId, cameraId, api1CameraId, facing, sensorOrientation,
                clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
                forceSlowJpegMode);
        ALOGI("%s: Camera1 API (legacy), override to portrait %d, forceSlowJpegMode %d",
                __FUNCTION__, overrideToPortrait, forceSlowJpegMode);
    } else { // Camera2 API route
        sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
        *client = new CameraDeviceClient(cameraService, tmp,
                cameraService->mCameraServiceProxyWrapper, packageName, systemNativeClient,
                featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
                overrideForPerfClass, overrideToPortrait);
        ALOGI("%s: Camera2 API, override to portrait %d", __FUNCTION__, overrideToPortrait);
    }
    return Status::ok();
}

到这里会根据effectiveApiLevel创建Camera2Client还是CameraDeviceClient, 他们都继承自Camera2ClientBase ,继承关系如下,

graph TD
    A["Camera2Client (API_1)" ] --> C
    B["CameraDeviceClient (API_2)"] --> C
    C[Camera2ClientBase ]
    

这里主要介绍API_2过程,API_1可以自行查看 在阅读源码的时候需要注意CameraDeviceClientCamera2ClientBase都有实现initializeinitializeImpl方法切都被调用 源码路径: frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
        const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
        std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
        const String16& clientPackageName,
        bool systemNativeClient,
        const std::optional<String16>& clientFeatureId,
        const String8& cameraId,
        int cameraFacing,
        int sensorOrientation,
        int clientPid,
        uid_t clientUid,
        int servicePid,
        bool overrideForPerfClass,
        bool overrideToPortrait) :
    Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper, clientPackageName,
            systemNativeClient, clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing,
            sensorOrientation, clientPid, clientUid, servicePid, overrideForPerfClass,
            overrideToPortrait),
    mInputStream(),
    mStreamingRequestId(REQUEST_ID_NONE),
    mRequestIdCounter(0),
    mPrivilegedClient(false),
    mOverrideForPerfClass(overrideForPerfClass) {

    ATRACE_CALL();
    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
}
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
        const sp<CameraService>& cameraService,
        const sp<TCamCallbacks>& remoteCallback,
        std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
        const String16& clientPackageName,
        bool systemNativeClient,
        const std::optional<String16>& clientFeatureId,
        const String8& cameraId,
        int api1CameraId,
        int cameraFacing,
        int sensorOrientation,
        int clientPid,
        uid_t clientUid,
        int servicePid,
        bool overrideForPerfClass,
        bool overrideToPortrait,
        bool legacyClient):
        TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
                clientUid, servicePid, overrideToPortrait),
        mSharedCameraCallbacks(remoteCallback),
        mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
        mDeviceActive(false), mApi1CameraId(api1CameraId)
{
    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
            String8(clientPackageName).string(), clientPid, clientUid);

    mClientPackageName = clientPackageName;
    mInitialClientPid = clientPid;
    mOverrideForPerfClass = overrideForPerfClass;
    mLegacyClient = legacyClient;
}

这里看一下CameraDeviceClient 构造函数中 mInputStream 这个变量是个结构体,看一下这个结构体

struct InputStreamConfiguration {
    bool configured;
    int32_t width;
    int32_t height;
    int32_t format;
    int32_t id;
} mInputStream;

这个结构体有宽,有高,有格式,猜想一定和图像输入有关。 在回头看connectHelper中代码:

Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
        int clientPid, apiLevel effectiveApiLevel, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
    
    // 省略无关细节代码 .....
    sp<CLIENT> client = nullptr;
    {
        // 省略无关细节代码 .....
        sp<BasicClient> tmp = nullptr;
        // 创建连接,
        bool overrideForPerfClass = SessionConfigurationUtils::targetPerfClassPrimaryCamera(
                mPerfClassPrimaryCameraIds, cameraId.string(), targetSdkVersion);
        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, facing, orientation,
                clientPid, clientUid, getpid(),
                deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                overrideToPortrait, forceSlowJpegMode,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        // 获取创建的 CameraDeviceClient
        client = static_cast<CLIENT*>(tmp.get());

        // 省略无关细节代码 .....
        // 初始化 deviceCline
        err = client->initialize(mCameraProviderManager, monitorTags);
        // 省略无关细节代码 .....
    } 
    device = client;
    return ret;
}

创建client 后就紧接着进行了初始化。这里需要注意一下,传入的mCameraProviderManager是在系统启动的时候加载CameraServices的时候创建的CameraProviderManager, 不了解的可以查看《Android12 Camera -开机初始化过程》

CameraDeviceClient初始化过程

status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
    ATRACE_CALL();
    status_t res;
    // 调用父类Camera2ClientBase 进行初始化
    res = Camera2ClientBase::initialize(providerPtr, monitorTags);
    if (res != OK) {
        return res;
    }

    String8 threadName;
    // 创建frame 数据处理线程
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
    // 启动线程
    res = mFrameProcessor->run(threadName.string());
    if (res != OK) {
        ALOGE("%s: Unable to start frame processor thread: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }

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

    const CameraMetadata &deviceInfo = mDevice->info();
    //省略无关代码......

    mProviderManager = providerPtr;
    // Cache physical camera ids corresponding to this device and also the high
    // resolution sensors in this device + physical camera ids
    mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
    return OK;
}

上面初始化注意到在开始的位置便调用了Camera2ClientBase的初始化函数,在创建FrameProcessorBase时构造函数中传入了一个mDevice,下面看一下Camera2ClientBase是初始化都做了什么?mDevice是什么时候被创建的?

template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {
    ATRACE_CALL();
    ALOGV("%s: Initializing client for camera %s", __FUNCTION__,
          TClientBase::mCameraIdStr.string());
    status_t res;
    
    IPCTransport providerTransport = IPCTransport::INVALID;
    // 获取驱动的通讯方式
    res = providerPtr->getCameraIdIPCTransport(TClientBase::mCameraIdStr.string(),
            &providerTransport);
    if (res != OK) {
        return res;
    }
    switch (providerTransport) {
        case IPCTransport::HIDL:
            mDevice =
                    new HidlCamera3Device(mCameraServiceProxyWrapper,
                            TClientBase::mCameraIdStr, mOverrideForPerfClass,
                            TClientBase::mOverrideToPortrait, mLegacyClient);
            break;
        case IPCTransport::AIDL:
            mDevice =
                    new AidlCamera3Device(mCameraServiceProxyWrapper,
                            TClientBase::mCameraIdStr, mOverrideForPerfClass,
                            TClientBase::mOverrideToPortrait, mLegacyClient);
             break;
        default:
            ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
                    TClientBase::mCameraIdStr.string());
            return NO_INIT;
    }
    if (mDevice == NULL) {
        ALOGE("%s: Camera %s: No device connected",
                __FUNCTION__, TClientBase::mCameraIdStr.string());
        return NO_INIT;
    }
    // 初始化报名
    res = mDevice->initializePackageName(TClientBase::mClientPackageName);
    // 初始化Device
    res = mDevice->initialize(providerPtr, monitorTags);
    if (res != OK) {
        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }

    // Verify ops permissions
    // 检查权限
    res = TClientBase::startCameraOps();
    if (res != OK) {
        TClientBase::finishCameraOps();
        return res;
    }

    wp<NotificationListener> weakThis(this);
    // 设置监听
    res = mDevice->setNotifyCallback(weakThis);
    if (res != OK) {
        ALOGE("%s: Camera %s: Unable to set notify callback: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }
    // 省略无关代码.......
    return OK;
}

Camera2ClientBase中会判断初始化HidlCamera3Device还是AidlCamera3Device, 他们都继承自Camera3Device ,继承关系如下:

graph TD
    A["HidlCamera3Device" ] --> C
    B["AidlCamera3Device"] --> C
    C[Camera3Device ]
    

上面是他们三个的关系,下面看一下Device的初始化, 这里需要注意一下,HidlCamera3Device, AidlCamera3DeviceCamera3Device都有initialize函数,但是在Android14中Camera3Device中的initialize函数没有被调用,下面我们就只看AidlCamera3DeviceHidlCamera3Device的初始话函数

status_t HidlCamera3Device::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    ATRACE_CALL();
    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);

    ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
    if (mStatus != STATUS_UNINITIALIZED) {
        CLOGE("Already initialized!");
        return INVALID_OPERATION;
    }
    if (manager == nullptr) return INVALID_OPERATION;

    sp<ICameraDeviceSession> session;
    ATRACE_BEGIN("CameraHal::openSession");
    // 打开一个和Hal层通讯的会话
    status_t res = manager->openHidlSession(mId.string(), this,
            /*out*/ &session);
    ATRACE_END();
    if (res != OK) {
        SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
        return res;
    }
    // 过去Camera 参数
    res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo,
            /*overrideToPortrait*/false);
    if (res != OK) {
        SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
        session->close();
        return res;
    }
    mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
    
    // 省略部分代码

    // 获取请求参数队列
    std::shared_ptr<RequestMetadataQueue> queue;
    auto requestQueueRet = session->getCaptureRequestMetadataQueue(
        [&queue](const auto& descriptor) {
            queue = std::make_shared<RequestMetadataQueue>(descriptor);
            if (!queue->isValid() || queue->availableToWrite() <= 0) {
                ALOGE("HAL returns empty request metadata fmq, not use it");
                queue = nullptr;
                // don't use the queue onwards.
            }
        });
    if (!requestQueueRet.isOk()) {
        ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
                requestQueueRet.description().c_str());
        return DEAD_OBJECT;
    }
    
    //结果参数队列
    std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
    auto resultQueueRet = session->getCaptureResultMetadataQueue(
        [&resQueue](const auto& descriptor) {
            resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
            if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
                ALOGE("HAL returns empty result metadata fmq, not use it");
                resQueue = nullptr;
                // Don't use the resQueue onwards.
            }
        });
    if (!resultQueueRet.isOk()) {
        ALOGE("Transaction error when getting result metadata queue from camera session: %s",
                resultQueueRet.description().c_str());
        return DEAD_OBJECT;
    }
    // 省略部分代码

    camera_metadata_entry bufMgrMode =
            mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
    if (bufMgrMode.count > 0) {
         mUseHalBufManager = (bufMgrMode.data.u8[0] ==
            ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
    }

    camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
    for (size_t i = 0; i < capabilities.count; i++) {
        uint8_t capability = capabilities.data.u8[i];
        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
            mSupportOfflineProcessing = true;
        }
    }
    // 创建Hidl Hal调用接口
    mInterface = new HidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);

    std::string providerType;
    mVendorTagId = manager->getProviderTagIdLocked(mId.string());
    mTagMonitor.initialize(mVendorTagId);
    if (!monitorTags.isEmpty()) {
        mTagMonitor.parseTagsToMonitor(String8(monitorTags));
    }

    // Metadata tags needs fixup for monochrome camera device version less
    // than 3.5.
    hardware::hidl_version maxVersion{0,0};
    IPCTransport transport = IPCTransport::HIDL;
    res = manager->getHighestSupportedVersion(mId.string(), &maxVersion, &transport);
    if (res != OK) {
        ALOGE("%s: Error in getting camera device version id: %s (%d)",
                __FUNCTION__, strerror(-res), res);
        return res;
    }
    int deviceVersion = HARDWARE_DEVICE_API_VERSION(
            maxVersion.get_major(), maxVersion.get_minor());

    bool isMonochrome = false;
    for (size_t i = 0; i < capabilities.count; i++) {
        uint8_t capability = capabilities.data.u8[i];
        if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
            isMonochrome = true;
        }
    }
    mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);

    return initializeCommonLocked();
}

上面代码主要步骤:

  1. 通过CameraProviderManager 去打开一个会话openHidlSession,
  2. 创建一个Hidl类型的Hal调用接口HidlHalInterface
  3. 调用initializeCommonLocked函数

AidlCamera3Device 初始化过程类似,这里不在介绍。

到这里看下上面提到的openHidlSession函数实现,openHidlSession 实现在 CameraProviderManager.cpp 中, 这里通过CameraProviderManageropenHidlSession获得一个ICameraDeviceSession frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

status_t CameraProviderManager::openHidlSession(const std::string &id,
        const sp<device::V3_2::ICameraDeviceCallback>& callback,
        /*out*/
        sp<device::V3_2::ICameraDeviceSession> *session) {

    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    // 根据id 查找对应Camera 驱动信息
    auto deviceInfo = findDeviceInfoLocked(id);
    if (deviceInfo == nullptr) return NAME_NOT_FOUND;

    auto *hidlDeviceInfo3 = static_cast<HidlProviderInfo::HidlDeviceInfo3*>(deviceInfo);
    // 通过开机时加载的 Camera device 获取对应的 ProviderInfo
    sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
    if (parentProvider == nullptr) {
        return DEAD_OBJECT;
    }
    
    // 通过binder 获取hal CameraProvider 服务调用接口, 下面会分析
    const sp<provider::V2_4::ICameraProvider> provider =
            static_cast<HidlProviderInfo *>(parentProvider.get())->startProviderInterface();
    if (provider == nullptr) {
        return DEAD_OBJECT;
    }
    std::shared_ptr<HalCameraProvider> halCameraProvider =
            std::make_shared<HidlHalCameraProvider>(provider, provider->descriptor);
    saveRef(DeviceMode::CAMERA, id, halCameraProvider);

    Status status;
    hardware::Return<void> ret;
     // 获取Camera device 接口
    auto interface = hidlDeviceInfo3->startDeviceInterface();
    if (interface == nullptr) {
        return DEAD_OBJECT;
    }
    // 打开 Camera device
    ret = interface->open(callback, [&status, &session]
            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    // 打开成功返回打开的 camera device session
                    // 这个 *session 是调用函数是传入的指针
                    *session = cameraSession;
                }
            });
    if (!ret.isOk()) {
        removeRef(DeviceMode::CAMERA, id);
        ALOGE("%s: Transaction error opening a session for camera device %s: %s",
                __FUNCTION__, id.c_str(), ret.description().c_str());
        return DEAD_OBJECT;
    }
    return HidlProviderInfo::mapToStatusT(status);
}

执行步骤:

  1. 获取CameraProvider服务的binder startProviderInterface()
  2. 获取驱动的接口startDeviceInterface()
  3. 执行打开驱动

下面看一下上面提到的调用startProviderInterface函数获取CameraProvider服务的binder的过程: frameworks/av/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp

const sp<provider::V2_4::ICameraProvider> 
HidlProviderInfo::startProviderInterface() {
    // 省略无关细节代码 .....
    auto interface = mActiveInterface.promote();
    if (interface == nullptr) {
        // Try to get service without starting
        // 获取 ICameraProvider binder接口
        interface = mManager->mHidlServiceProxy->tryGetService(mProviderName);
        if (interface == nullptr) {
            ALOGV("Camera provider actually needs restart, calling getService(%s)",
                  mProviderName.c_str());
            // 获取 ICameraProvider binder接口
            interface = mManager->mHidlServiceProxy->getService(mProviderName);

            for (auto& device : mDevices) {
              device->mIsDeviceAvailable = false;
            }

            interface->setCallback(this);
            // 设置bind 断开监听
            hardware::Return<bool>linked = interface->linkToDeath(this, /*cookie*/ mId);
            if (!linked.isOk()) {
              mManager->removeProvider(mProviderInstance);
              return nullptr;
            } else if (!linked) {
              ALOGW("%s: Unable to link to provider '%s' death notifications",
                    __FUNCTION__, mProviderName.c_str());
            }
            // Send current device state
            if (mMinorVersion >= 5) {
              auto castResult =
                  provider::V2_5::ICameraProvider::castFrom(interface);
              if (castResult.isOk()) {
                sp<provider::V2_5::ICameraProvider> interface_2_5 = castResult;
                if (interface_2_5 != nullptr) {
                  ALOGV("%s: Initial device state for %s: 0x %" PRIx64,
                        __FUNCTION__, mProviderName.c_str(), mDeviceState);
                  interface_2_5->notifyDeviceStateChange(mDeviceState);
                }
              }
            }
        }
        mActiveInterface = interface;
    } else {
        ALOGV("Camera provider (%s) already in use. Re-using instance.",
              mProviderName.c_str());
    }

    return interface;
}

看一下获取驱动的接口startDeviceInterface(),这个函数也在HidlProviderInfo.cpp中。

sp<hardware::camera::device::V3_2::ICameraDevice>
HidlProviderInfo::HidlDeviceInfo3::startDeviceInterface() {
    Mutex::Autolock l(mDeviceAvailableLock);
    sp<hardware::camera::device::V3_2::ICameraDevice> device;
    ATRACE_CALL();
    if (mSavedInterface == nullptr) {
        sp<HidlProviderInfo> parentProvider = static_cast<HidlProviderInfo *>(mParentProvider.promote().get());
        if (parentProvider != nullptr) {
            // Wait for lazy HALs to confirm device availability
            if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
                ALOGV("%s: Wait for external device to become available %s",
                      __FUNCTION__,
                      mId.c_str());

                auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
                                                         kDeviceAvailableTimeout);
                if (res != OK) {
                    ALOGE("%s: Failed waiting for device to become available",
                          __FUNCTION__);
                    return nullptr;
                }
            }

            device = parentProvider->startDeviceInterface(mName);
        }
    } else {
        device = (hardware::camera::device::V3_2::ICameraDevice *) mSavedInterface.get();
    }
    return device;
}

sp<device::V3_2::ICameraDevice>
HidlProviderInfo::startDeviceInterface(const std::string &name) {
    Status status;
    sp<device::V3_2::ICameraDevice> cameraInterface;
    hardware::Return<void> ret;
    // 这里又调用了startProviderInterface();函数获取了ICameraProvider
    const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
    if (interface == nullptr) {
        return nullptr;
    }
    ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
        Status s, sp<device::V3_2::ICameraDevice> interface) {
                status = s;
                // 成功获取到Camera Device 接口
                cameraInterface = interface;
            });
    if (!ret.isOk()) {
        ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
                __FUNCTION__, name.c_str(), ret.description().c_str());
        return nullptr;
    }
    if (status != Status::OK) {
        ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
                name.c_str(), statusToString(status));
        return nullptr;
    }
    return cameraInterface;
}

执行步骤:

  1. 获取CameraProvider服务的binder startProviderInterface()
  2. 调用getCameraDeviceInterface_V3_x函数获取Camera Device 的引用

到这里调用了ICameraProvider两个函数:

  1. interface->getCameraDeviceInterface_V3_x
  2. interface->open

上面这两个函数调用是调用到Camera Hal中,代码位置: Device:hardware/interfaces/camera/device Provide:hardware/interfaces/camera/provider 这里不介绍,感兴趣可以自己查看

interface->open函数调用完,Camera便已经打开了,最后看一下initializeCommonLocked();函数

上面是打开hal层Camera 到获取到 *session 的过程。下面我们看一下获取到*session 之后还做了些什么,下面继续看Camera3Device.cppinitialize函数最后一行的initializeCommonLocked()函数

status_t Camera3Device::initializeCommonLocked() {

   
     // 启动一个线程获取状态
    mStatusTracker = new StatusTracker(this);
    status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
     //省略无关细节代码 .....

    // 创建一个相机图像输出流 buffer管理器
    mBufferManager = new Camera3BufferManager();

    //省略无关细节代码 .....

    // 启动请求队列线程
    mRequestThread = createNewRequestThread(
            this, mStatusTracker, mInterface, sessionParamKeys,
            mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait,
            mSupportZoomOverride);
    res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
    
    //省略无关细节代码 .....
    mPreparerThread = new PreparerThread();

    //省略无关细节代码 .....
    // Hidl/AidlCamera3DeviceInjectionMethods
    mInjectionMethods = createCamera3DeviceInjectionMethods(this);

    //省略无关细节代码 .....

    return OK;
}

执行到这里,初始化的过程就执行完毕了。

最后在看一下CameraService::connectHelper函数中

// 3 second busy timeout when other clients are connecting
static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000;

template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, const String16& clientPackageNameMaybe, bool systemNativeClient,
        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
        bool overrideToPortrait, bool forceSlowJpegMode,
        /*out*/sp<CLIENT>& device) {
    // 省略无关代码.....
    {

        // 省略无关代码.....
        // 创建Camera连接
        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, facing, orientation,
                clientPid, clientUid, getpid(),
                deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                overrideToPortrait, forceSlowJpegMode,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());

        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);

        String8 monitorTags = isClientWatched(client.get()) ? mMonitorTags : String8("");
        // 初始化当前Camera 连接
        err = client->initialize(mCameraProviderManager, monitorTags);

        // 省略无关代码.....
        if (shimUpdateOnly) {
            // If only updating legacy shim parameters, immediately disconnect client
            mServiceLock.unlock();
            client->disconnect();
            mServiceLock.lock();
        } else {
            // Otherwise, add client to active clients list
            // 连接创建完成
            finishConnectLocked(client, partial, oomScoreOffset, systemNativeClient);
        }

        // 省略无关代码.....
    } // lock is destroyed, allow further connect calls

    // 省略无关代码.....

    return ret;
}

上面是再次精简后的代码代码, 初始化完成后执行到finishConnectLocked函数。

void CameraService::finishConnectLocked(const sp<BasicClient>& client,
        const CameraService::DescriptorPtr& desc, int oomScoreOffset, bool systemNativeClient) {

    // 创建一个Camera连接描述
    auto clientDescriptor =CameraService::CameraClientManager::makeClientDescriptor(client, desc,
                    oomScoreOffset, systemNativeClient);
    
    // 将成功打开的连接添加到管理器中
    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);

    // 省略无关代码.....
    sp<IBinder> remoteCallback = client->getRemote();
    if (remoteCallback != nullptr) {
        remoteCallback->linkToDeath(this);
    }
}

在这个函数中主要创建一个Camera的连接描述(ClientDescriptor), 然后将这个描述添加的CameraClientManager中进行管理。

到这里Camera2中openCamera函数的执行过程就介绍完了。