Android Camera2 openCamera流程详解(1)

本文用Android 11 的代码进行梳理。

Android Camera2 open Camera的接口为CameraManager的openCamera函数,如下:

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
648      @RequiresPermission(android.Manifest.permission.CAMERA)
649      public void openCamera(@NonNull String cameraId,
650              @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
651              throws CameraAccessException {
    
    
652  
653          openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
654                  USE_CALLING_UID);
655      }
  1. 调用该函数需要android.Manifest.permission.CAMERA权限
  2. 第一个参数为相机的ID
  3. 第二个参数为打开相机操作的回调对象,打开失败或者成功时会回调callback的相应的函数
  4. 第三个参数为Handler,callback将在该handler对应的线程执行,若该参数为空,则callback在当前线程中执行
  5. 调用CameraManager的openCameraForUid函数

调用openCameraForUid之前会先对参数handler做一些处理:

frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2190      public static Executor checkAndWrapHandler(Handler handler) {
    
    
2191          return new CameraHandlerExecutor(checkHandler(handler));
2192      }

用checkHandler返回值为参数构造CameraHandlerExecutor对象并返回。

frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2202      static Handler checkHandler(Handler handler) {
    
    
2203          if (handler == null) {
    
    
2204              Looper looper = Looper.myLooper();
2205              if (looper == null) {
    
    
2206                  throw new IllegalArgumentException(
2207                      "No handler given, and current thread has no looper!");
2208              }
2209              handler = new Handler(looper);
2210          }
2211          return handler;
2212      }
  1. 如果handler为空,则以当前线程的looper对象为参数构造Handler对象并返回
  2. 如果handler不为空,则直接返回handler
frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
2144      private static class CameraHandlerExecutor implements Executor {
    
    
2145          private final Handler mHandler;
2146  
2147          public CameraHandlerExecutor(@NonNull Handler handler) {
    
    
2148              mHandler = Objects.requireNonNull(handler);
2149          }
2150  
2151          @Override
2152          public void execute(Runnable command) {
    
    
2153              // Return value of 'post()' will be ignored in order to keep the
2154              // same camera behavior. For further details see b/74605221 .
2155              mHandler.post(command);
2156          }
2157      }
  1. 将参数handler赋值给成员变量mHandler,Objects.requireNonNull的参数为空时会抛出空指针异常
  2. 执行execute函数时实际上是调用的mHandler的post函数

回到openCameraForUid函数的分析:

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
第四个参数为USE_CALLING_UID值为-1
711      public void openCameraForUid(@NonNull String cameraId,
712              @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
713              int clientUid)
714              throws CameraAccessException {
    
    
715  
716          if (cameraId == null) {
    
    
717              throw new IllegalArgumentException("cameraId was null");
718          } else if (callback == null) {
    
    
719              throw new IllegalArgumentException("callback was null");
720          }
721          if (CameraManagerGlobal.sCameraServiceDisabled) {
    
    
722              throw new IllegalArgumentException("No cameras available on device");
723          }
724  
725          openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
726      }
  1. cameraId为空,抛出IllegalArgumentException异常
  2. callback为空,抛出IllegalArgumentException异常
  3. sCameraServiceDisabled为空,抛出IllegalArgumentException异常
  4. 调用 openCameraDeviceUserAsync 函数,该函数内容较多,分段分析

(1)根据cameraId获取CameraCharacteristics对象。

 CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);

getCameraCharacteristics的实现:

//获取CameraService代理对象
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
//获取屏幕显示尺寸参数
Size displaySize = getDisplaySize();
//调用CameraService的getCameraCharacteristics函数返回CameraMetadataNative对象
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
//设置CameraMetadataNative对象的一些参数
try {
    
    
	info.setCameraId(Integer.parseInt(cameraId));
} catch (NumberFormatException e) {
    
    
	// For external camera, reaching here is expected.
	Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
}
boolean hasConcurrentStreams =
CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
info.setDisplaySize(displaySize); 
//以CameraMetadataNative为参数构造CameraCharacteristics对象返回
characteristics = new CameraCharacteristics(info);

继续看下CameraService里的getCameraCharacteristics函数

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

本章完,接下章。

微信公众号将会同步发布,欢迎扫码关注!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41678668/article/details/124184645
今日推荐