【camera-framework 002】从Java应用打开一个相机的全流程 1

这里追踪 相机打开流程,从 Java API 到 camera service,可以参照下面的核心类,进行追踪
在这里插入图片描述

1 openCamera

frameworks/base/core/java/android/hardware/camera2/CameraManager.java # openCamera
打开与给定ID的相机的连接。
下面是一些注意点,简单看一下:

使用{@link #getCameraIdList}来获取可用相机设备的列表。请注意,即使列出了id,如果设备在调用{@ link# getCameraIdList}和{@ link# openCamera}之间断开连接,或者如果更高优先级的相机API客户端开始使用相机设备,则打开可能会失败。

一旦相机成功打开,{@link CameraDevice。StateCallback#onOpened}将与新打开的{@link CameraDevice}一起调用。然后可以通过调用{@link CameraDevice#createCaptureSession}和{@link CameraDevice#createCaptureRequest}来设置相机设备进行操作。

在API级别30之前,当应用程序尝试打开多个不同id的{@link CameraDevice}并且设备不支持打开这样的组合时,{@link #openCamera}将失败并抛出{@link CameraAccessException}或一个或多个已打开的{@link CameraDevice}将断开连接并接收{@link android.硬件。camera2.CameraDevice.StateCallback # onDisconnected}的回调函数。哪种行为会发生取决于设备实现,并且在不同的设备上可能会有所不同。从API级别30开始,如果设备不支持正在打开的相机组合,则可以保证{@link #openCamera}调用将失败,并且现有的{@link CameraDevice}都不会断开连接。

由于相机设备将被异步打开,任何在返回的CameraDevice实例上完成的异步操作将被排队,直到设备启动完成和回调的{@link CameraDevice.StateCallback#onOpened onOpened}方法被调用。然后按顺序处理挂起的操作。

  * @param cameraId
  *             The unique identifier of the camera device to open
  * @param callback
  *             The callback which is invoked once the camera is opened
  * @param handler
  *             The handler on which the callback should be invoked, or
  *             {
   @code null} to use the current thread's {
   @link android.os.Looper looper}.
// Open a connection to a camera with the given ID.

 @RequiresPermission(android.Manifest.permission.CAMERA)
 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);
 }
 
  

2 追踪 openCamera 具体做了哪些事情

我们重点看一下 打开相机的过程做了哪些事情:

2.1 openCameraForUid

可以看到 openCamera指定用于权限等验证的UID为 USE_CALLING_UID,用来通过权限认证

/**
     * Open a connection to a camera with the given ID, on behalf of another application
     * specified by clientUid.
     代表由clientUid指定的另一个应用程序,打开给定ID的相机的连接。
     *
     * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
     * the caller to specify the UID to use for permission/etc verification. This can only be
     * done by services trusted by the camera subsystem to act on behalf of applications and
     * to forward the real UID.</p>
     *
     * @param clientUid
     *             The UID of the application on whose behalf the camera is being opened.
     *             Must be USE_CALLING_UID unless the caller is a trusted service.
     *
     * @hide
     */
    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));
    }

2.2 openCameraDeviceUserAsync

frameworks/base/core/java/android/hardware/camera2/CameraManager.java # openCameraDeviceUserAsync
真正的逻辑在这里开始


    /**
     * Helper for opening a connection to a camera with the given ID.
     *
     * @param cameraId The unique identifier of the camera device to open
     * @param callback The callback for the camera. Must not be null.
     * @param executor The executor to invoke the callback with. Must not be null.
     * @param uid      The UID of the application actually opening the camera.
     *                 Must be USE_CALLING_UID unless the caller is a service
     *                 that is trusted to open the device on behalf of an
     *                 application and to forward the real UID.
     *
     * @throws CameraAccessException if the camera is disabled by device policy,
     * too many camera devices are already open, or the cameraId does not match
     * any currently available camera device.
     *
     * @throws SecurityException if the application does not have permission to
     * access the camera
     * @throws IllegalArgumentException if callback or handler is null.
     * @return A handle to the newly-created camera device.
     *
     * @see #getCameraIdList
     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
     */
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid,
            final int oomScoreOffset, boolean overrideToPortrait) throws CameraAccessException {
   
          // 返回的信息,包括是否有强制并发流的标志,int 类型的camera id, display size, 可能得 多分辨率流配置       
        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
        
        CameraDevice device = null;
        // 返回 getPhysicalCameraIds()返回的physicalCameraId作为key, 
        // getCameraCharacteristics(physicalCameraId)返回的 CameraCharacteristics 作为 value的 map
        Map<String, CameraCharacteristics> physicalIdsToChars =
                getPhysicalIdToCharsMap(characteristics);
        synchronized (mLock) {
   

            ICameraDeviceUser cameraUser 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值