android_驱动_qcom_【高通SDM660平台】(5) --- Camera Open 流程 及 后续更新思路



后续更新思路


【高通SDM660平台】(1) — Camera 驱动 Bringup Guide
【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析
【高通SDM660平台】(3) — Camera V4L2 驱动层分析
【高通SDM660平台】(4) — Camera Init 初始化流程
【高通SDM660平台】(5) — Camera Open 流程
【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程
【高通SDM660平台】(7) — Camera onPreview 代码流程
【高通SDM660平台】(8) — Camera MetaData介绍
【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析
【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析
《【高通SDM660平台】Camera Capture 流程》
《【高通SDM660平台】Camera mm-qcamera-app 代码分析》




一、Camera Open 总结

整个Camera Open 过程总结如下:

  1. Java APP 层
    调用 Frameworks 层 Camera.java 中的 open() 方法,
    在open camera 后,才开始调用对应的 getParameters()setParameters()startPreview() 等 函数,这些后续分析

  2. Frameworks 层 Camera.java 中的 open()
    (1) 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄
    (2) 根据传入的 camera id 进行初始化
    (3) 注册 EventHandler 循环监听Camera 事件
    (4) 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号

  3. JNI 层 android_hardware_Camera_native_setup
    (1) 调用 Camera::connect() 函数,connect 为 AIDL 方法,通过binder 调用到服务端CameraService.cpp中的 CameraService::connect() 方法中
    (2) 获取 Camera Class,建立专门负责与java Camera对象通信的对象
    (3) 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand 下发屏幕显示方向

  4. C++ Native 层 CameraService.cpp
    (1) CameraService.cpp 是camera 初始化中讲过了,在开机时会注册好对应的 cameraservice 服务
    (2) 前面AIDL中,调用到 CameraService.cpp中的 CameraService::connect() 方法 在该方法中,
    (3) 首先检查是否存在 client ,如果存在的话直接返回
    (4) 关闭所有的 flashlight 对象
    (5) 调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象
    (6) 调用client->initialize对前面创建好的 Camera client 进行初始化
    (7) 初始化前先对device 进行初始化 ,在Camera3Device->initialize()中打开对应的 Camera 节点/dev/videox,进行初始化,获取到 Camera 的操作方法
    (8) 初始化 Camera 默认参数
    (9) 接着对创建 Camera 运行时的六大线程,
    处理preview和录像 stream的线程、处理3A和人脸识别的线程、拍照流程状态机线程、处理拍照 jpeg stream 线程、处理零延时zsl stream使用的线程、处理callback的线程

二、Camera Open 代码流程分析

2.1 Java 层 Camera Class 使用介绍

先看下谷歌官方对 Camera Class 的介绍:

The Camera class is used to set image capture settings, start/stop preview, 
					snap pictures, and retrieve frames for encoding for video. 
This Class is a client for the Camera service, which manages the actual camera hardware.

To access the device camera,
you must declare the {@link android.Manifest.permission#CAMERA} permission in your Android Manifest.

Also be sure to include the uses-feature manifest element to declare camera features used by your application.

For example,
if you use the camera and auto-focus feature, your Manifest should include the following:

uses-permission android:name = “android.permission.CAMERA”
uses-feature android:name = “android.hardware.camera”
uses-feature android:name = “android.hardware.camera.autofocus”

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.1.1 拍照官方流程

  1. 获取 Camera 对象
    Obtain an instance of Camera from {@link #open(int)}.

  2. 获取默认参数(例如默认分辨率、帧率等 )
    Get existing (default) settings with {@link #getParameters()}.

  3. 设置并下发 Camera 参数
    If necessary, modify the returned {@link Camera.Parameters} object and call {@link #setParameters(Camera.Parameters)}.

  4. 设置屏幕显示方向
    If desired, call {@link #setDisplayOrientation(int)}.

  5. 传递一个完全初始化的 SurfaceHolder,调用setPreviewDisplay(SurfaceHolder),否则无法preview
    Important: Pass a fully initialized {@link SurfaceHolder} to {@link #setPreviewDisplay(SurfaceHolder)}.
    Without a surface, the camerawill be unable to start the preview.

  6. 调用 startPreview() 开始预览,拍照之前必须先预览
    Important: Call {@link #startPreview()} to start updating the preview surface.
    Preview must be started before you can take a picture.

  7. 调用takePicture() 开始拍照时,等待它的回调函数回传数据
    When you want, call {@link #takePicture(Camera.ShutterCallback,Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)} to capture a photo.
    Wait for the callbacks to provide the actual image data.

  8. 拍照完后,preview会停止。如果想继续拍照,需重新调用 startPreview()
    After taking a picture, preview display will have stopped.
    To take morephotos, call {@link #startPreview()} again first.

  9. 调用stopPreview()停止更新预览界面
    Call {@link #stopPreview()} to stop updating the preview surface.

  10. 调用 release() 释放Camera 资源
    Important: Call {@link #release()} to release the camera foruse by other applications.
    Applications should release the cameraimmediately in {@link android.app.Activity#onPause()}
    (and re-{@link #open()} it in {@link android.app.Activity#onResume()}).


2.1.2 录像官方流程

  1. 获取并初始化 Camera 对像,并调用 startPreview()
    Obtain and initialize a Camera and start preview as described above.

  2. 调用 unlock() 允许 media 进程操作Camera
    Call {@link #unlock()} to allow the media process to access the camera.

  3. 调用 setCamera(Camera) 将 Camera 对像传递给 MediaRecorder
    Pass the camera to {@link android.media.MediaRecorder#setCamera(Camera)}.
    See {@link android.media.MediaRecorder} information about video recording.

  4. 当录像完毕后,调用 reconnect() 重新锁定Camera
    When finished recording, call {@link #reconnect()} to re-acquireand re-lock the camera.

  5. 如果想拍照,重新preview ,然后拍照
    If desired, restart preview and take more photos or videos.

  6. 调用 stopPreview()release() 退出预览并释放Camera资源
    Call {@link #stopPreview()} and {@link #release()} as described above.

This class is not thread-safe, and is meant for use from one event thread.
Most long-running operations (preview, focus, photo capture, etc) happen asynchronously and invoke callbacks as necessary.
Callbacks will be invoked on the event thread {@link #open(int)} was called from.
This class’s methods must never be called from multiple threads at once.

Caution:
Different Android-powered devicesmay have different hardware specifications,
such as megapixel ratings and auto-focus capabilities.
In order for your application to be compatible with more devices,
you should not make assumptions about the device camera specifications.

2.2 Frameworks 层 Camera.java 分析

调用 Frameworks 层 Camera.java 中的 open() 方法,
在open camera 后,才开始调用对应的 getParameters(),setParameters(), startPreview() 等 函数,这些后续分析

Java 层中调用的 Camera Class 源码位于 frameworks/base/core/java/android/hardware/Camera.java

整个过程,主要工作如下:
(1) 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄
(2) 根据传入的 camera id 进行初始化
(3) 注册 EventHandler 循环监听Camera 事件
(4) 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号

@ frameworks/base/core/java/android/hardware/Camera.java

public class Camera {
private static final String TAG = “Camera”;

<span class="token keyword">private</span> CameraDataCallback mCameraDataCallback<span class="token punctuation">;</span>
<span class="token keyword">private</span> CameraMetaDataCallback mCameraMetaDataCallback<span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_HAL_API_VERSION_1_0 <span class="token operator">=</span> <span class="token number">0x100</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">CameraInfo</span> <span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_FACING_BACK <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_FACING_FRONT <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_SUPPORT_MODE_ZSL <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">int</span> CAMERA_SUPPORT_MODE_NONZSL <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> facing<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> orientation<span class="token punctuation">;</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> canDisableShutterSound<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token comment">// 1. 找开指定 id 的Camera</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Camera <span class="token function">open</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Camera</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 2. 在Camera open() 函数中,如果没有指定open 对应的camera id,则默认打开后摄</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Camera <span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">int</span> numberOfCameras <span class="token operator">=</span> <span class="token function">getNumberOfCameras</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    CameraInfo cameraInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">CameraInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> numberOfCameras<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">getCameraInfo</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> cameraInfo<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">==</span> CameraInfo<span class="token punctuation">.</span>CAMERA_FACING_BACK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Camera</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 3. 调用 cameraInitNormal() 初始对应 id 的Camera</span>
<span class="token comment">/** used by Camera#open, Camera#open(int) */</span>
<span class="token function">Camera</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">int</span> err <span class="token operator">=</span> <span class="token function">cameraInitNormal</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">private</span> <span class="token keyword">int</span> <span class="token function">cameraInitNormal</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">cameraInitVersion</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> CAMERA_HAL_API_VERSION_NORMAL_CONNECT<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// -2</span>
<span class="token punctuation">}</span>

<span class="token keyword">private</span> <span class="token keyword">int</span> <span class="token function">cameraInitVersion</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">,</span> <span class="token keyword">int</span> halVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mShutterCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>	
    mRawImageCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    mJpegCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    mPreviewCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    mPostviewCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    mUsingPreviewAllocation <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    mZoomListener <span class="token operator">=</span> null<span class="token punctuation">;</span>
    <span class="token comment">/* ### QC ADD-ONS: START */</span>
    mCameraDataCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    mCameraMetaDataCallback <span class="token operator">=</span> null<span class="token punctuation">;</span>
    <span class="token comment">/* ### QC ADD-ONS: END */</span>

	<span class="token comment">// 1. 注册 EventHandler 循环监听Camera 事件</span>
    Looper looper<span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>looper <span class="token operator">=</span> Looper<span class="token punctuation">.</span><span class="token function">myLooper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mEventHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventHandler</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> looper<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>looper <span class="token operator">=</span> Looper<span class="token punctuation">.</span><span class="token function">getMainLooper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mEventHandler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventHandler</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> looper<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        mEventHandler <span class="token operator">=</span> null<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">// 2. 获取当前包名</span>
    String packageName <span class="token operator">=</span> ActivityThread<span class="token punctuation">.</span><span class="token function">currentOpPackageName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token comment">// 3. 如果定义了 prop 属性 "camera.hal1.packagelist" , 则强制使用 HAL1</span>
    <span class="token comment">//Force HAL1 if the package name falls in this bucket</span>
    String packageList <span class="token operator">=</span> SystemProperties<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"camera.hal1.packagelist"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>packageList<span class="token punctuation">.</span><span class="token function">length</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        TextUtils<span class="token punctuation">.</span>StringSplitter splitter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TextUtils<span class="token punctuation">.</span>SimpleStringSplitter</span><span class="token punctuation">(</span><span class="token string">','</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        splitter<span class="token punctuation">.</span><span class="token function">setString</span><span class="token punctuation">(</span>packageList<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span>String str <span class="token operator">:</span> splitter<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>packageName<span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                halVersion <span class="token operator">=</span> CAMERA_HAL_API_VERSION_1_0<span class="token punctuation">;</span>
                <span class="token keyword">break</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 4. 调用 native_setup() JNI 函数,并下发 camera id 、当前包名、hal层版本号</span>
    <span class="token keyword">return</span> <span class="token function">native_setup</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">WeakReference</span><span class="token generics function"><span class="token punctuation">&lt;</span>Camera<span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> packageName<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

2.2.1 [JNI] CameraService初始化 native_setup( ) —> android_hardware_Camera_native_setup( )

java 中通过JNI 调用 native 方法,Camera JNI 代码位于

//cameraId = 0
//halVersion = -2
native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);

@ frameworks/base/core/jni/android_hardware_Camera.cpp
static const JNINativeMethod camMethods[] = {
{ “_getNumberOfCameras”, “()I”, (void )android_hardware_Camera_getNumberOfCameras },
{ “_getCameraInfo”, “(ILandroid/hardware/Camera$CameraInfo;)V”, (void)android_hardware_Camera_getCameraInfo },
{ “native_setup”, “(Ljava/lang/Object;IILjava/lang/String;)I”, (void)android_hardware_Camera_native_setup },
{ “native_release”, “()V”, (void)android_hardware_Camera_release },
{ “setPreviewSurface”, “(Landroid/view/Surface;)V”, (void )android_hardware_Camera_setPreviewSurface },
{ “setPreviewTexture”, “(Landroid/graphics/SurfaceTexture;)V”, (void )android_hardware_Camera_setPreviewTexture },
{ “setPreviewCallbackSurface”, “(Landroid/view/Surface;)V”, (void )android_hardware_Camera_setPreviewCallbackSurface },
{ “startPreview”, “()V”, (void )android_hardware_Camera_startPreview },
{ “_stopPreview”, “()V”, (void )android_hardware_Camera_stopPreview },
{ “previewEnabled”, “()Z”, (void )android_hardware_Camera_previewEnabled },
{ “setHasPreviewCallback”,"(ZZ)V", (void )android_hardware_Camera_setHasPreviewCallback },
{ “_addCallbackBuffer”, “([BI)V”, (void )android_hardware_Camera_addCallbackBuffer },
{ “native_autoFocus”, “()V”, (void )android_hardware_Camera_autoFocus },
{ “native_cancelAutoFocus”,"()V", (void )android_hardware_Camera_cancelAutoFocus },
{ “native_takePicture”, “(I)V”, (void )android_hardware_Camera_takePicture },
{ “native_setHistogramMode”,"(Z)V", (void )android_hardware_Camera_setHistogramMode },
{ “native_setMetadataCb”, “(Z)V”, (void )android_hardware_Camera_setMetadataCb },
{ “native_sendHistogramData”,"()V", (void )android_hardware_Camera_sendHistogramData },
{ “native_setLongshot”, “(Z)V”, (void )android_hardware_Camera_setLongshot },
{ “native_setParameters”, “(Ljava/lang/String;)V”, (void )android_hardware_Camera_setParameters },
{ “native_getParameters”, “()Ljava/lang/String;”, (void )android_hardware_Camera_getParameters },
{ “reconnect”, “()V”, (void)android_hardware_Camera_reconnect },
{ “lock”, “()V”, (void)android_hardware_Camera_lock },
{ “unlock”, “()V”, (void)android_hardware_Camera_unlock },
{ “startSmoothZoom”, “(I)V”, (void )android_hardware_Camera_startSmoothZoom },
{ “stopSmoothZoom”, “()V”, (void )android_hardware_Camera_stopSmoothZoom },
{ “setDisplayOrientation”,"(I)V", (void )android_hardware_Camera_setDisplayOrientation },
{ “_enableShutterSound”, “(Z)Z”, (void )android_hardware_Camera_enableShutterSound },
{ “_startFaceDetection”, “(I)V”, (void )android_hardware_Camera_startFaceDetection },
{ “_stopFaceDetection”, “()V”, (void )android_hardware_Camera_stopFaceDetection},
{ “enableFocusMoveCallback”,"(I)V", (void *)android_hardware_Camera_enableFocusMoveCallback},
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
    // Convert jstring to String16
    const char16_t *rawClientName = reinterpret_cast<const char16_t*>(env->GetStringChars(clientPackageName, NULL));
    jsize rawClientNameLen = env->GetStringLength(clientPackageName);
    String16 clientName(rawClientName, rawClientNameLen);
    env->ReleaseStringChars(clientPackageName, reinterpret_cast<const jchar*>(rawClientName));
sp<span class="token generics function"><span class="token punctuation">&lt;</span>Camera<span class="token punctuation">&gt;</span></span> camera<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>halVersion <span class="token operator">==</span> CAMERA_HAL_API_VERSION_NORMAL_CONNECT<span class="token punctuation">)</span> <span class="token punctuation">{</span>		<span class="token comment">// -2</span>
    <span class="token comment">// Default path: hal version is don't care, do normal camera connect.</span>
    <span class="token comment">// 调用 Camera::connect() 函数,connect 为 AIDL 方法,</span>
    <span class="token comment">// 通过binder 调用到服务端CameraService.cpp中的 CameraService::connect() 方法中</span>
    camera <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientName<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_UID<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_PID<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span> 
    <span class="token operator">+</span>	<span class="token comment">// frameworks/av/camera/Camera.cpp</span>
    <span class="token operator">+</span>	<span class="token keyword">return</span> CameraBaseT<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span> 
    <span class="token operator">+</span>		<span class="token comment">// frameworks/av/camera/CameraBase.cpp</span>
    <span class="token operator">+</span>		sp<span class="token generics function"><span class="token punctuation">&lt;</span>TCam<span class="token punctuation">&gt;</span></span> CameraBase<span class="token generics function"><span class="token punctuation">&lt;</span>TCam<span class="token punctuation">,</span> TCamTraits<span class="token punctuation">&gt;</span></span><span class="token operator">:</span><span class="token operator">:</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token keyword">int</span> cameraId<span class="token punctuation">,</span> <span class="token keyword">const</span> String16<span class="token operator">&amp;</span> clientPackageName<span class="token punctuation">,</span> <span class="token keyword">int</span> clientUid<span class="token punctuation">,</span> <span class="token keyword">int</span> clientPid<span class="token punctuation">)</span>
    <span class="token operator">+</span>		<span class="token punctuation">{</span>
    <span class="token operator">+</span>		<span class="token operator">-</span>	sp<span class="token generics function"><span class="token punctuation">&lt;</span>TCam<span class="token punctuation">&gt;</span></span> c <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TCam</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>		<span class="token operator">-</span>	sp<span class="token generics function"><span class="token punctuation">&lt;</span>TCamCallbacks<span class="token punctuation">&gt;</span></span> cl <span class="token operator">=</span> c<span class="token punctuation">;</span>
    <span class="token operator">+</span>			<span class="token keyword">const</span> sp<span class="token operator">&lt;</span><span class="token operator">:</span><span class="token operator">:</span>android<span class="token operator">:</span><span class="token operator">:</span>hardware<span class="token operator">:</span><span class="token operator">:</span>ICameraService<span class="token operator">&gt;</span> cs <span class="token operator">=</span> <span class="token function">getCameraService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>			TCamConnectService fnConnectService <span class="token operator">=</span> TCamTraits<span class="token operator">:</span><span class="token operator">:</span>fnConnectService<span class="token punctuation">;</span>
    <span class="token operator">+</span>			ret <span class="token operator">=</span> <span class="token punctuation">(</span>cs<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token operator">*</span>fnConnectService<span class="token punctuation">)</span><span class="token punctuation">(</span>cl<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> <span class="token comment">/*out*/</span> <span class="token operator">&amp;</span>c<span class="token operator">-</span><span class="token operator">&gt;</span>mCamera<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>			<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">&gt;</span>
    <span class="token operator">+</span>				CameraTraits<span class="token generics function"><span class="token punctuation">&lt;</span>Camera<span class="token punctuation">&gt;</span></span><span class="token operator">:</span><span class="token operator">:</span>TCamConnectService CameraTraits<span class="token generics function"><span class="token punctuation">&lt;</span>Camera<span class="token punctuation">&gt;</span></span><span class="token operator">:</span><span class="token operator">:</span>fnConnectService <span class="token operator">=</span> 
    <span class="token operator">+</span>								<span class="token operator">&amp;</span><span class="token operator">:</span><span class="token operator">:</span>android<span class="token operator">:</span><span class="token operator">:</span>hardware<span class="token operator">:</span><span class="token operator">:</span>ICameraService<span class="token operator">:</span><span class="token operator">:</span>connect<span class="token punctuation">;</span>
    <span class="token operator">+</span>				
    <span class="token operator">+</span>			IInterface<span class="token operator">:</span><span class="token operator">:</span><span class="token function">asBinder</span><span class="token punctuation">(</span>c<span class="token operator">-</span><span class="token operator">&gt;</span>mCamera<span class="token punctuation">)</span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">linkToDeath</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token operator">+</span>			<span class="token keyword">return</span> c<span class="token punctuation">;</span>
    <span class="token operator">+</span>		<span class="token punctuation">}</span>
    <span class="token operator">+</span>		<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
    <span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    jint status <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">connectLegacy</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> clientName<span class="token punctuation">,</span> Camera<span class="token operator">:</span><span class="token operator">:</span>USE_CALLING_UID<span class="token punctuation">,</span> camera<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> status<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// make sure camera hardware is alive</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>camera<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">getStatus</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> NO_INIT<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 获取 Camera Class</span>
jclass clazz <span class="token operator">=</span> env<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">GetObjectClass</span><span class="token punctuation">(</span>thiz<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>clazz <span class="token operator">==</span> NULL<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// This should never happen</span>
    <span class="token function">jniThrowRuntimeException</span><span class="token punctuation">(</span>env<span class="token punctuation">,</span> <span class="token string">"Can't find android/hardware/Camera"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> INVALID_OPERATION<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// We use a weak reference so the Camera object can be garbage collected.</span>
<span class="token comment">// The reference is only used as a proxy for callbacks.</span>
sp<span class="token generics function"><span class="token punctuation">&lt;</span>JNICameraContext<span class="token punctuation">&gt;</span></span> context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">JNICameraContext</span><span class="token punctuation">(</span>env<span class="token punctuation">,</span> weak_this<span class="token punctuation">,</span> clazz<span class="token punctuation">,</span> camera<span class="token punctuation">)</span><span class="token punctuation">;</span>
context<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">incStrong</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token operator">*</span><span class="token punctuation">)</span>android_hardware_Camera_native_setup<span class="token punctuation">)</span><span class="token punctuation">;</span>
camera<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setListener</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>	<span class="token comment">// 专门负责与java Camera对象通信的对象 </span>

<span class="token comment">// save context in opaque field</span>
env<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">SetLongField</span><span class="token punctuation">(</span>thiz<span class="token punctuation">,</span> fields<span class="token punctuation">.</span>context<span class="token punctuation">,</span> <span class="token punctuation">(</span>jlong<span class="token punctuation">)</span>context<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// Update default display orientation in case the sensor is reverse-landscape</span>
CameraInfo cameraInfo<span class="token punctuation">;</span>
status_t rc <span class="token operator">=</span> Camera<span class="token operator">:</span><span class="token operator">:</span><span class="token function">getCameraInfo</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> <span class="token operator">&amp;</span>cameraInfo<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> defaultOrientation <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>orientation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">case</span> <span class="token number">0</span><span class="token operator">:</span> <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> <span class="token number">90</span><span class="token operator">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">==</span> CAMERA_FACING_FRONT<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> <span class="token number">180</span><span class="token operator">:</span>
        defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">case</span> <span class="token number">270</span><span class="token operator">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraInfo<span class="token punctuation">.</span>facing <span class="token operator">!=</span> CAMERA_FACING_FRONT<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            defaultOrientation <span class="token operator">=</span> <span class="token number">180</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token keyword">default</span><span class="token operator">:</span>
        <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"Unexpected camera orientation %d!"</span><span class="token punctuation">,</span> cameraInfo<span class="token punctuation">.</span>orientation<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 如果没有设置屏幕显示方向,则默认为0,如果不为0,调用sendCommand 下发屏幕显示方向</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>defaultOrientation <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">ALOGV</span><span class="token punctuation">(</span><span class="token string">"Setting default display orientation to %d"</span><span class="token punctuation">,</span> defaultOrientation<span class="token punctuation">)</span><span class="token punctuation">;</span>
    rc <span class="token operator">=</span> camera<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">sendCommand</span><span class="token punctuation">(</span>CAMERA_CMD_SET_DISPLAY_ORIENTATION<span class="token punctuation">,</span>defaultOrientation<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> NO_ERROR<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

2.2.2 [AIDL] interface ICameraService

在前面代码中, 经过如下一系列调用,最终走到了 AIDL 层。

native_setup() —> android_hardware_Camera_native_setup() —> CameraBaseT::connect —> sp<TCam> CameraBase<TCam, TCamTraits>::connect —> ret = (cs.get()->*fnConnectService) —> ::android::hardware::ICameraService::connect()

fnConnectService 定义如下:

CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &::android::hardware::ICameraService::connect;

frameworks/av/camera/aidl/android/hardware/ICameraService.aidl

/**

  • Binder interface for the native camera service running in mediaserver.

  • @hide
    /
    interface ICameraService
    {
    /
    * Open a camera device through the old camera API */
    ICamera connect(ICameraClient client, int cameraId, String opPackageName, int clientUid, int clientPid);

    /** Open a camera device through the new camera API Only supported for device HAL versions >= 3.2 */
    ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,String opPackageName,int clientUid);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

AIDL 中,我们走的是老方法, ICamera connect().

AIDL——Android Interface Definition Language,是一种接口定义语言,用于生成可以在Android设备上两个进程间进行通信的代码。
Android Java Service Framework提供的大多数系统服务都是使用AIDL语言生成的。使用AIDL语言,可以自动生成服务接口、服务代理、服务Stub代码。

2.2.3 [Native] CameraService.cpp

通过 AIDL 的 Binder 通信,跳转到 CameraService.cpp 中。

CameraService.cpp 是camera 初始化中讲过了,在开机时会注册好对应的 cameraservice 服务

还记得前面我们 《【高通SDM660平台】Camera Init 初始化流程》文章中,CameraService 服务已经注册好了,
此时就是通过Binder通信,调用CameraService 服务中的 connect 方法:

@frameworks/av/services/camera/libcameraservice/CameraService.cpp 
Status CameraService::connect(
        const sp<ICameraClient>& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        int clientPid,
        /*out*/
        sp<ICamera>* device) {
String8 id <span class="token operator">=</span> String8<span class="token operator">::</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"%d"</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
sp<span class="token operator">&lt;</span>Client<span class="token operator">&gt;</span> client <span class="token operator">=</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
ret <span class="token operator">=</span> connectHelper<span class="token operator">&lt;</span>ICameraClient<span class="token punctuation">,</span>Client<span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraClient<span class="token punctuation">,</span> id<span class="token punctuation">,</span>
        CAMERA_HAL_API_VERSION_UNSPECIFIED<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> API_1<span class="token punctuation">,</span>
        <span class="token comment">/*legacyMode*/</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">/*shimUpdateOnly*/</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
        <span class="token comment">/*out*/</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token operator">*</span>device <span class="token operator">=</span> client<span class="token punctuation">;</span>
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

进入 connectHelper 函数看下:

  1. 检查 Client 的权限
  2. 如果已存在 client 则直接返回
  3. 在打开Camera 前,所有Flashlight 都应该被关闭
  4. 调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象
  5. 调用client->initialize对前面创建好的 Camera client 进行初始化
template<class CALLBACK, class CLIENT>
binder::Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();
String8 <span class="token function">clientName8</span><span class="token punctuation">(</span>clientPackageName<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> originalClientPid <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

<span class="token function">ALOGI</span><span class="token punctuation">(</span><span class="token string">"CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "</span>
        <span class="token string">"Camera API version %d"</span><span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> clientName8<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">(</span>halVersion <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token string">"default"</span> <span class="token punctuation">:</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">to_string</span><span class="token punctuation">(</span>halVersion<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> static_cast<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>effectiveApiLevel<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

sp<span class="token operator">&lt;</span>CLIENT<span class="token operator">&gt;</span> client <span class="token operator">=</span> nullptr<span class="token punctuation">;</span>
<span class="token punctuation">{</span>
	<span class="token comment">// 1. 检查 Client 的权限</span>
    <span class="token comment">// Enforce client permissions and do basic sanity checks</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">validateConnectLocked</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> clientName8<span class="token punctuation">,</span>  <span class="token comment">/*inout*/</span>clientUid<span class="token punctuation">,</span> <span class="token comment">/*inout*/</span>clientPid<span class="token punctuation">,</span> <span class="token comment">/*out*/</span>originalClientPid<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    sp<span class="token operator">&lt;</span>BasicClient<span class="token operator">&gt;</span> clientTmp <span class="token operator">=</span> nullptr<span class="token punctuation">;</span>
    std<span class="token punctuation">:</span><span class="token punctuation">:</span>shared_ptr<span class="token operator">&lt;</span>resource_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>ClientDescriptor<span class="token operator">&lt;</span>String8<span class="token punctuation">,</span> sp<span class="token operator">&lt;</span>BasicClient<span class="token operator">&gt;&gt;</span><span class="token operator">&gt;</span> partial<span class="token punctuation">;</span>
    err <span class="token operator">=</span> <span class="token function">handleEvictionsLocked</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">,</span> originalClientPid<span class="token punctuation">,</span> effectiveApiLevel<span class="token punctuation">,</span>
            IInterface<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">asBinder</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">)</span><span class="token punctuation">,</span> clientName8<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&amp;</span>clientTmp<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&amp;</span>partial<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">// 2. 如果已存在 client 则直接返回</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>clientTmp<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> nullptr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Handle special case for API1 MediaRecorder where the existing client is returned</span>
        device <span class="token operator">=</span> static_cast<span class="token operator">&lt;</span>CLIENT<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>clientTmp<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
	<span class="token comment">// 3. 在打开Camera 前,所有Flashlight 都应该被关闭</span>
    <span class="token comment">// give flashlight a chance to close devices if necessary.</span>
    mFlashlight<span class="token operator">-&gt;</span><span class="token function">prepareDeviceOpen</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">// TODO: Update getDeviceVersion + HAL interface to use strings for Camera IDs</span>
    <span class="token keyword">int</span> id <span class="token operator">=</span> <span class="token function">cameraIdToInt</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">int</span> facing <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span> deviceVersion <span class="token operator">=</span> <span class="token function">getDeviceVersion</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> <span class="token comment">/*out*/</span><span class="token operator">&amp;</span>facing<span class="token punctuation">)</span><span class="token punctuation">;</span>
    sp<span class="token operator">&lt;</span>BasicClient<span class="token operator">&gt;</span> tmp <span class="token operator">=</span> nullptr<span class="token punctuation">;</span>
	
	<span class="token comment">// 4.  调用makeClient() 创建 Camera Client 对象。 client是通过 Camera2ClientBase() 进行创建的,同时创建Camera3Device 对象</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ret <span class="token operator">=</span> <span class="token function">makeClient</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> cameraCb<span class="token punctuation">,</span> clientPackageName<span class="token punctuation">,</span> id<span class="token punctuation">,</span> facing<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span>
            clientUid<span class="token punctuation">,</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> legacyMode<span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span> effectiveApiLevel<span class="token punctuation">,</span>
            <span class="token comment">/*out*/</span><span class="token operator">&amp;</span>tmp<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isOk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> ret<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    client <span class="token operator">=</span> static_cast<span class="token operator">&lt;</span>CLIENT<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>tmp<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// Camera2Client</span>

    <span class="token function">LOG_ALWAYS_FATAL_IF</span><span class="token punctuation">(</span>client<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> nullptr<span class="token punctuation">,</span> <span class="token string">"%s: CameraService in invalid state"</span><span class="token punctuation">,</span>
            __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">// 5. 调用client-&gt;initialize对前面创建好的 Camera client 进行初始化</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>err <span class="token operator">=</span> client<span class="token operator">-&gt;</span><span class="token function">initialize</span><span class="token punctuation">(</span>mModule<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Could not initialize client from HAL module."</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// Errors could be from the HAL module open call or from AppOpsManager</span>
        <span class="token keyword">switch</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">case</span> BAD_VALUE<span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_ILLEGAL_ARGUMENT<span class="token punctuation">,</span>
                        <span class="token string">"Illegal argument to HAL module for camera \"%s\""</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> <span class="token operator">-</span>EBUSY<span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_CAMERA_IN_USE<span class="token punctuation">,</span>
                        <span class="token string">"Camera \"%s\" is already open"</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> <span class="token operator">-</span>EUSERS<span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_MAX_CAMERAS_IN_USE<span class="token punctuation">,</span>
                        <span class="token string">"Too many cameras already open, cannot open camera \"%s\""</span><span class="token punctuation">,</span>
                        cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> PERMISSION_DENIED<span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_PERMISSION_DENIED<span class="token punctuation">,</span>
                        <span class="token string">"No permission to open camera \"%s\""</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> <span class="token operator">-</span>EACCES<span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_DISABLED<span class="token punctuation">,</span>
                        <span class="token string">"Camera \"%s\" disabled by policy"</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">case</span> <span class="token operator">-</span>ENODEV<span class="token punctuation">:</span>
            <span class="token keyword">default</span><span class="token punctuation">:</span>
                <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_INVALID_OPERATION<span class="token punctuation">,</span>
                        <span class="token string">"Failed to initialize camera \"%s\": %s (%d)"</span><span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                        <span class="token function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>err<span class="token punctuation">)</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// Update shim paremeters for legacy clients</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Assume we have always received a Client subclass for API1</span>
        sp<span class="token operator">&lt;</span>Client<span class="token operator">&gt;</span> shimClient <span class="token operator">=</span> reinterpret_cast<span class="token operator">&lt;</span>Client<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>client<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        String8 rawParams <span class="token operator">=</span> shimClient<span class="token operator">-&gt;</span><span class="token function">getParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        CameraParameters <span class="token function">params</span><span class="token punctuation">(</span>rawParams<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">auto</span> cameraState <span class="token operator">=</span> <span class="token function">getCameraState</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>cameraState <span class="token operator">!=</span> nullptr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            cameraState<span class="token operator">-&gt;</span><span class="token function">setShimParams</span><span class="token punctuation">(</span>params<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
            <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Cannot update shim parameters for camera %s, no such device exists."</span><span class="token punctuation">,</span>
                    __FUNCTION__<span class="token punctuation">,</span> cameraId<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>shimUpdateOnly<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// If only updating legacy shim parameters, immediately disconnect client</span>
        mServiceLock<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        client<span class="token operator">-&gt;</span><span class="token function">disconnect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        mServiceLock<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">// Otherwise, add client to active clients list</span>
        <span class="token function">finishConnectLocked</span><span class="token punctuation">(</span>client<span class="token punctuation">,</span> partial<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token comment">// lock is destroyed, allow further connect calls</span>

<span class="token comment">// Important: release the mutex here so the client can call back into the service from its</span>
<span class="token comment">// destructor (can be at the end of the call)</span>
device <span class="token operator">=</span> client<span class="token punctuation">;</span>
<span class="token keyword">return</span> ret<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

2.2.3.1 [HAL] 创建 Camera 客户端 makeClient( )

接着调用
makeClient(this, cameraCb, clientPackageName, id, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /*out*/&tmp))

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

Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/out/sp<BasicClient>* client) {

<span class="token keyword">if</span> <span class="token punctuation">(</span>halVersion <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> halVersion <span class="token operator">==</span> deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// Default path: HAL version is unspecified by caller, create CameraClient</span>
    <span class="token comment">// based on device version reported by the HAL.</span>
    <span class="token keyword">switch</span><span class="token punctuation">(</span>deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token comment">// Camera1 API route</span>
            sp<span class="token operator">&lt;</span>ICameraClient<span class="token operator">&gt;</span> tmp <span class="token operator">=</span> static_cast<span class="token operator">&lt;</span>ICameraClient<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
                    clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> <span class="token function">getpid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Camera2 API route</span>
            <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Camera using old HAL version: %d"</span><span class="token punctuation">,</span> deviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_DEPRECATED_HAL<span class="token punctuation">,</span>
                    <span class="token string">"Camera device \"%d\" HAL version %d does not support camera2 API"</span><span class="token punctuation">,</span>
                    cameraId<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_0<span class="token punctuation">:</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_1<span class="token punctuation">:</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_2<span class="token punctuation">:</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_3<span class="token punctuation">:</span>
      <span class="token keyword">case</span> CAMERA_DEVICE_API_VERSION_3_4<span class="token punctuation">:</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>effectiveApiLevel <span class="token operator">==</span> API_1<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Camera1 API route</span>
            sp<span class="token operator">&lt;</span>ICameraClient<span class="token operator">&gt;</span> tmp <span class="token operator">=</span> static_cast<span class="token operator">&lt;</span>ICameraClient<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">Camera2Client</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
                    clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Camera2 API route</span>
            sp<span class="token operator">&lt;</span>hardware<span class="token punctuation">:</span><span class="token punctuation">:</span>camera2<span class="token punctuation">:</span><span class="token punctuation">:</span>ICameraDeviceCallbacks<span class="token operator">&gt;</span> tmp <span class="token operator">=</span>
                    static_cast<span class="token operator">&lt;</span>hardware<span class="token punctuation">:</span><span class="token punctuation">:</span>camera2<span class="token punctuation">:</span><span class="token punctuation">:</span>ICameraDeviceCallbacks<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraDeviceClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span>
                    facing<span class="token punctuation">,</span> clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token comment">// A particular HAL version is requested by caller. Create CameraClient</span>
    <span class="token comment">// based on the requested HAL version.</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>deviceVersion <span class="token operator">&gt;</span> CAMERA_DEVICE_API_VERSION_1_0 <span class="token operator">&amp;&amp;</span>
        halVersion <span class="token operator">==</span> CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Only support higher HAL version device opened as HAL1.0 device.</span>
        sp<span class="token operator">&lt;</span>ICameraClient<span class="token operator">&gt;</span> tmp <span class="token operator">=</span> static_cast<span class="token operator">&lt;</span>ICameraClient<span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>cameraCb<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token operator">*</span>client <span class="token operator">=</span> new <span class="token function">CameraClient</span><span class="token punctuation">(</span>cameraService<span class="token punctuation">,</span> tmp<span class="token punctuation">,</span> packageName<span class="token punctuation">,</span> cameraId<span class="token punctuation">,</span> facing<span class="token punctuation">,</span>
                clientPid<span class="token punctuation">,</span> clientUid<span class="token punctuation">,</span> servicePid<span class="token punctuation">,</span> legacyMode<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">// Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.</span>
        <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"Invalid camera HAL version %x: HAL %x device can only be"</span>
                <span class="token string">" opened as HAL %x device"</span><span class="token punctuation">,</span> halVersion<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span>
                CAMERA_DEVICE_API_VERSION_1_0<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token function">STATUS_ERROR_FMT</span><span class="token punctuation">(</span>ERROR_ILLEGAL_ARGUMENT<span class="token punctuation">,</span>
                <span class="token string">"Camera device \"%d\" (HAL version %d) cannot be opened as HAL version %d"</span><span class="token punctuation">,</span>
                cameraId<span class="token punctuation">,</span> deviceVersion<span class="token punctuation">,</span> halVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> Status<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">ok</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

接着调用 *client = new Camera2Client(cameraService, tmp, packageName, cameraId, facing, clientPid, clientUid, servicePid, legacyMode);
client是通过 Camera2ClientBase() 进行创建的

@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
        const sp<hardware::ICameraClient>& cameraClient,
        const String16& clientPackageName,
        int cameraId,
        int cameraFacing,
        int clientPid,
        uid_t clientUid,
        int servicePid,
        bool legacyMode):
        Camera2ClientBase(cameraService, cameraClient, clientPackageName,
                cameraId, cameraFacing, clientPid, clientUid, servicePid),
		mParameters(cameraId, cameraFacing)
{
    ATRACE_CALL();
SharedParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>Lock <span class="token function">l</span><span class="token punctuation">(</span>mParameters<span class="token punctuation">)</span><span class="token punctuation">;</span>
l<span class="token punctuation">.</span>mParameters<span class="token punctuation">.</span>state <span class="token operator">=</span> Parameters<span class="token punctuation">:</span><span class="token punctuation">:</span>DISCONNECTED<span class="token punctuation">;</span>

mLegacyMode <span class="token operator">=</span> legacyMode<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

创建Camera3Device 对象

// Interface used by CameraService

template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
int cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(cameraId)),
mDeviceActive(false)
{
ALOGI(“Camera %d: Opened. Client: %s (PID %d, UID %d)”, cameraId, String8(clientPackageName).string(), clientPid, clientUid);

mInitialClientPid <span class="token operator">=</span> clientPid<span class="token punctuation">;</span>
mDevice <span class="token operator">=</span> new <span class="token function">Camera3Device</span><span class="token punctuation">(</span>cameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOG_ALWAYS_FATAL_IF</span><span class="token punctuation">(</span>mDevice <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">"Device should never be NULL here."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

@ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

Camera3Device::Camera3Device(int id):
mId(id),
mIsConstrainedHighSpeedConfiguration(false),
mHal3Device(NULL),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextShutterFrameNumber(0),
mNextReprocessShutterFrameNumber(0),
mListener(NULL)
{
ATRACE_CALL();
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %d", FUNCTION, id);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

2.2.3.2 [HAL] Camera2Client初始化 client->initialize(mModule))
  1. 调用 Camera3Device::initialize 对/dev/videox 调备节点进行初始化,获取对应的设备的opt 操作函数
  2. 初始化 Camera 默认参数
  3. 创建 Camera 运行时的六大线程
    3.1 StreamingProcessor:用来处理preview和录像 stream的线程。
    3.2 FrameProcessor:用来处理3A和人脸识别的线程。
    3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。
    3.4 JpegProcessor:用来处理拍照 jpeg stream 线程
    3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程
    3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程
@ frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp

status_t Camera2Client::initialize(CameraModule *module)
{
ATRACE_CALL();
ALOGV("%s: Initializing client for camera %d", FUNCTION, mCameraId);
status_t res;

<span class="token comment">// 1. 调用 Camera3Device::initialize 进行设备初始化,获取对应的 camera device 的opt 操作函数</span>
res <span class="token operator">=</span> Camera2ClientBase<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">initialize</span><span class="token punctuation">(</span>module<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span> 
	@ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>device3<span class="token operator">/</span>Camera3Device<span class="token punctuation">.</span>cpp
	mDevice<span class="token operator">-&gt;</span><span class="token function">initialize</span><span class="token punctuation">(</span>module<span class="token punctuation">)</span><span class="token punctuation">;</span>
	mDevice<span class="token operator">-&gt;</span><span class="token function">setNotifyCallback</span><span class="token punctuation">(</span>weakThis<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">// 2. 初始化 Camera  默认参数</span>
<span class="token punctuation">{</span>
    SharedParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>Lock <span class="token function">l</span><span class="token punctuation">(</span>mParameters<span class="token punctuation">)</span><span class="token punctuation">;</span>

    res <span class="token operator">=</span> l<span class="token punctuation">.</span>mParameters<span class="token punctuation">.</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">(</span>mDevice<span class="token operator">-&gt;</span><span class="token function">info</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> mDeviceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
	<span class="token operator">+</span>	@ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>api1<span class="token operator">/</span>client2<span class="token operator">/</span>Parameters<span class="token punctuation">.</span>cpp
	<span class="token operator">+</span>	status_t Parameters<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">initialize</span><span class="token punctuation">(</span><span class="token keyword">const</span> CameraMetadata <span class="token operator">*</span>info<span class="token punctuation">,</span> <span class="token keyword">int</span> deviceVersion<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token operator">+</span>		<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
	<span class="token operator">+</span>		videoWidth <span class="token operator">=</span> previewWidth<span class="token punctuation">;</span>
	<span class="token operator">+</span>		videoHeight <span class="token operator">=</span> previewHeight<span class="token punctuation">;</span>
	<span class="token operator">+</span>		params<span class="token punctuation">.</span><span class="token function">setPreviewSize</span><span class="token punctuation">(</span>previewWidth<span class="token punctuation">,</span> previewHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>	    params<span class="token punctuation">.</span><span class="token function">setVideoSize</span><span class="token punctuation">(</span>videoWidth<span class="token punctuation">,</span> videoHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>	    params<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>CameraParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO<span class="token punctuation">,</span> 
	<span class="token operator">+</span>	    				String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"%dx%d"</span><span class="token punctuation">,</span> previewWidth<span class="token punctuation">,</span> previewHeight<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>	    params<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>CameraParameters<span class="token punctuation">:</span><span class="token punctuation">:</span>KEY_SUPPORTED_PREVIEW_FORMATS<span class="token punctuation">,</span> supportedPreviewFormats<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token operator">+</span>	    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>  省略一系列 参数初始化代码
	<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>
<span class="token punctuation">}</span>


String8 threadName<span class="token punctuation">;</span>
<span class="token comment">// 3. 创建 Camera 运行时的六大线程</span>
<span class="token comment">// 3.1 StreamingProcessor:用来处理preview和录像 stream的线程。</span>
mStreamingProcessor <span class="token operator">=</span> new <span class="token function">StreamingProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-StreamProc"</span><span class="token punctuation">,</span> mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mFrameProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3.2 FrameProcessor:用来处理3A和人脸识别的线程。</span>
mFrameProcessor <span class="token operator">=</span> new <span class="token function">FrameProcessor</span><span class="token punctuation">(</span>mDevice<span class="token punctuation">,</span> this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-FrameProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mFrameProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3.3 CaptureSequencer:拍照流程状态机线程,拍照的场景非常多,后面会发出状态机的运转流程。</span>
mCaptureSequencer <span class="token operator">=</span> new <span class="token function">CaptureSequencer</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-CaptureSeq"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mCaptureSequencer<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3.4 JpegProcessor:用来处理拍照 jpeg stream 线程</span>
mJpegProcessor <span class="token operator">=</span> new <span class="token function">JpegProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mCaptureSequencer<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-JpegProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mJpegProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3.5 ZslProcessor3:这个处理零延时zsl stream使用的线程</span>
mZslProcessor <span class="token operator">=</span> new <span class="token function">ZslProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mCaptureSequencer<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-ZslProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mZslProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3.6 mCallbackProcessor:处理callback的线程,主要包含对 callback stream 的创建函数 updateStream()以及处理 HAL 层传上来的 callback stream 的线程</span>
mCallbackProcessor <span class="token operator">=</span> new <span class="token function">CallbackProcessor</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
threadName <span class="token operator">=</span> String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C2-%d-CallbkProc"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
mCallbackProcessor<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>threadName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">return</span> OK<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

2.2.3.2.1 [HAL] Camera device 初始化 mDevice->initialize(module)
  1. 调用 hardware 层的camera_module_t.common 中的 open 方法,传入Camera ID
  2. 获取 Camera相关的信息
  3. 初始化 Camera 设备
@ frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::initialize(CameraModule *module)
{
    ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
    /** Open HAL device */
    String8 deviceName = String8::format("%d", mId);
camera3_device_t <span class="token operator">*</span>device<span class="token punctuation">;</span>
<span class="token function">ATRACE_BEGIN</span><span class="token punctuation">(</span><span class="token string">"camera3-&gt;open"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 1. 调用 hardware 层的camera_module_t.common 中的 open 方法,传入Camera ID</span>
res <span class="token operator">=</span> module<span class="token operator">-&gt;</span><span class="token function">open</span><span class="token punctuation">(</span>deviceName<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> reinterpret_cast<span class="token operator">&lt;</span>hw_device_t<span class="token operator">*</span><span class="token operator">*</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>device<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span> @ frameworks<span class="token operator">/</span>av<span class="token operator">/</span>services<span class="token operator">/</span>camera<span class="token operator">/</span>libcameraservice<span class="token operator">/</span>common<span class="token operator">/</span>CameraModule<span class="token punctuation">.</span>cpp 
<span class="token operator">+</span>	res <span class="token operator">=</span> <span class="token function">filterOpenErrorCode</span><span class="token punctuation">(</span>mModule<span class="token operator">-&gt;</span>common<span class="token punctuation">.</span>methods<span class="token operator">-&gt;</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mModule<span class="token operator">-&gt;</span>common<span class="token punctuation">,</span> id<span class="token punctuation">,</span> device<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>	<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>		@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>QCamera2Hal<span class="token punctuation">.</span>cpp 
<span class="token operator">+</span>		<span class="token keyword">struct</span> hw_module_methods_t QCamera2Factory<span class="token punctuation">:</span><span class="token punctuation">:</span>mModuleMethods <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>			<span class="token punctuation">.</span>open <span class="token operator">=</span> QCamera2Factory<span class="token punctuation">:</span><span class="token punctuation">:</span>camera_device_open<span class="token punctuation">,</span>
<span class="token operator">+</span>				<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>					@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>QCamera2Factory<span class="token punctuation">.</span>cpp
<span class="token operator">+</span>					rc <span class="token operator">=</span> gQCamera2Factory<span class="token operator">-&gt;</span><span class="token function">cameraDeviceOpen</span><span class="token punctuation">(</span><span class="token function">atoi</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">,</span> hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">+</span>		<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token operator">+</span>	<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token operator">+</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token comment">// 2. 获取 Camera相关的信息</span>
camera_info info<span class="token punctuation">;</span>
res <span class="token operator">=</span> module<span class="token operator">-&gt;</span><span class="token function">getCameraInfo</span><span class="token punctuation">(</span>mId<span class="token punctuation">,</span> <span class="token operator">&amp;</span>info<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 3. 初始化 Camera 设备,设置回调函数</span>
<span class="token comment">/** Initialize device with callback functions */</span>
<span class="token function">ATRACE_BEGIN</span><span class="token punctuation">(</span><span class="token string">"camera3-&gt;initialize"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
res <span class="token operator">=</span> device<span class="token operator">-&gt;</span>ops<span class="token operator">-&gt;</span><span class="token function">initialize</span><span class="token punctuation">(</span>device<span class="token punctuation">,</span> this<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">ATRACE_END</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>	@ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>HAL3<span class="token operator">/</span>QCamera3HWI<span class="token punctuation">.</span>cpp
<span class="token operator">+</span>	camera3_device_ops_t QCamera3HardwareInterface<span class="token punctuation">:</span><span class="token punctuation">:</span>mCameraOps <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token operator">+</span>		<span class="token punctuation">.</span>initialize			<span class="token operator">=</span> QCamera3HardwareInterface<span class="token punctuation">:</span><span class="token punctuation">:</span>initialize<span class="token punctuation">,</span>
<span class="token operator">+</span>		<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span>
<span class="token operator">+</span>			<span class="token keyword">int</span> rc <span class="token operator">=</span> hw<span class="token operator">-&gt;</span><span class="token function">initialize</span><span class="token punctuation">(</span>callback_ops<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span>

<span class="token comment">/** Start up status tracker thread */</span>
mStatusTracker <span class="token operator">=</span> new <span class="token function">StatusTracker</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>
res <span class="token operator">=</span> mStatusTracker<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C3Dev-%d-Status"</span><span class="token punctuation">,</span> mId<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!=</span> OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">SET_ERR_L</span><span class="token punctuation">(</span><span class="token string">"Unable to start status tracking thread: %s (%d)"</span><span class="token punctuation">,</span>
            <span class="token function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>res<span class="token punctuation">)</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span><span class="token punctuation">;</span>
    device<span class="token operator">-&gt;</span>common<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>device<span class="token operator">-&gt;</span>common<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mStatusTracker<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> res<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/** Register in-flight map to the status tracker */</span>
mInFlightStatusId <span class="token operator">=</span> mStatusTracker<span class="token operator">-&gt;</span><span class="token function">addComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/** Create buffer manager */</span>
mBufferManager <span class="token operator">=</span> new <span class="token function">Camera3BufferManager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

bool aeLockAvailable <span class="token operator">=</span> false<span class="token punctuation">;</span>
camera_metadata_ro_entry aeLockAvailableEntry<span class="token punctuation">;</span>
res <span class="token operator">=</span> <span class="token function">find_camera_metadata_ro_entry</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>static_camera_characteristics<span class="token punctuation">,</span>
        ANDROID_CONTROL_AE_LOCK_AVAILABLE<span class="token punctuation">,</span> <span class="token operator">&amp;</span>aeLockAvailableEntry<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">==</span> OK <span class="token operator">&amp;&amp;</span> aeLockAvailableEntry<span class="token punctuation">.</span>count <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    aeLockAvailable <span class="token operator">=</span> <span class="token punctuation">(</span>aeLockAvailableEntry<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span>
            ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">/** Start up request queue thread */</span>
mRequestThread <span class="token operator">=</span> new <span class="token function">RequestThread</span><span class="token punctuation">(</span>this<span class="token punctuation">,</span> mStatusTracker<span class="token punctuation">,</span> device<span class="token punctuation">,</span> aeLockAvailable<span class="token punctuation">)</span><span class="token punctuation">;</span>
res <span class="token operator">=</span> mRequestThread<span class="token operator">-&gt;</span><span class="token function">run</span><span class="token punctuation">(</span>String8<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"C3Dev-%d-ReqQueue"</span><span class="token punctuation">,</span> mId<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>res <span class="token operator">!=</span> OK<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">SET_ERR_L</span><span class="token punctuation">(</span><span class="token string">"Unable to start request queue thread: %s (%d)"</span><span class="token punctuation">,</span>
            <span class="token function">strerror</span><span class="token punctuation">(</span><span class="token operator">-</span>res<span class="token punctuation">)</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span><span class="token punctuation">;</span>
    device<span class="token operator">-&gt;</span>common<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>device<span class="token operator">-&gt;</span>common<span class="token punctuation">)</span><span class="token punctuation">;</span>
    mRequestThread<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> res<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

mPreparerThread <span class="token operator">=</span> new <span class="token function">PreparerThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">/** Everything is good to go */</span>

mDeviceVersion <span class="token operator">=</span> device<span class="token operator">-&gt;</span>common<span class="token punctuation">.</span>version<span class="token punctuation">;</span>
mDeviceInfo <span class="token operator">=</span> info<span class="token punctuation">.</span>static_camera_characteristics<span class="token punctuation">;</span>
mHal3Device <span class="token operator">=</span> device<span class="token punctuation">;</span>

<span class="token comment">// Determine whether we need to derive sensitivity boost values for older devices.</span>
<span class="token comment">// If post-RAW sensitivity boost range is listed, so should post-raw sensitivity control</span>
<span class="token comment">// be listed (as the default value 100)</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>mDeviceVersion <span class="token operator">&lt;</span> CAMERA_DEVICE_API_VERSION_3_4 <span class="token operator">&amp;&amp;</span>
        mDeviceInfo<span class="token punctuation">.</span><span class="token function">exists</span><span class="token punctuation">(</span>ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mDerivePostRawSensKey <span class="token operator">=</span> true<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">internalUpdateStatusLocked</span><span class="token punctuation">(</span>STATUS_UNCONFIGURED<span class="token punctuation">)</span><span class="token punctuation">;</span>
mNextStreamId <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
mDummyStreamId <span class="token operator">=</span> NO_STREAM<span class="token punctuation">;</span>
mNeedConfig <span class="token operator">=</span> true<span class="token punctuation">;</span>
mPauseStateNotify <span class="token operator">=</span> false<span class="token punctuation">;</span>

<span class="token comment">// Measure the clock domain offset between camera and video/hw_composer</span>
camera_metadata_entry timestampSource <span class="token operator">=</span>
        mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>timestampSource<span class="token punctuation">.</span>count <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> timestampSource<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span>
        ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mTimestampOffset <span class="token operator">=</span> <span class="token function">getMonoToBoottimeOffset</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// Will the HAL be sending in early partial result metadata?</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>mDeviceVersion <span class="token operator">&gt;=</span> CAMERA_DEVICE_API_VERSION_3_2<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    camera_metadata_entry partialResultsCount <span class="token operator">=</span>
            mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_REQUEST_PARTIAL_RESULT_COUNT<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>partialResultsCount<span class="token punctuation">.</span>count <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mNumPartialResults <span class="token operator">=</span> partialResultsCount<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
        mUsePartialResult <span class="token operator">=</span> <span class="token punctuation">(</span>mNumPartialResults <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    camera_metadata_entry partialResultsQuirk <span class="token operator">=</span>
            mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_QUIRKS_USE_PARTIAL_RESULT<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>partialResultsQuirk<span class="token punctuation">.</span>count <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> partialResultsQuirk<span class="token punctuation">.</span>data<span class="token punctuation">.</span>u8<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mUsePartialResult <span class="token operator">=</span> true<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

camera_metadata_entry configs <span class="token operator">=</span>
        mDeviceInfo<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>uint32_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> configs<span class="token punctuation">.</span>count<span class="token punctuation">;</span> i <span class="token operator">+</span><span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">==</span> HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED <span class="token operator">&amp;&amp;</span>
            configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token operator">==</span>
            ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        mSupportedOpaqueInputSizes<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token function">Size</span><span class="token punctuation">(</span>configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
                configs<span class="token punctuation">.</span>data<span class="token punctuation">.</span>i32<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">return</span> OK<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136

2.2.3.2.2 [Hardware] 打开设备 gQCamera2Factory->cameraDeviceOpen( )
@ hardware/qcom/camera/QCamera2/QCamera2Factory.cpp

int QCamera2Factory::cameraDeviceOpen(int camera_id, struct hw_device_t hw_device)
{
LOGI(“Open camera id %d API version %d”,camera_id, mHalDescriptors[camera_id].device_version);

<span class="token keyword">if</span> <span class="token punctuation">(</span> mHalDescriptors<span class="token punctuation">[</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">.</span>device_version <span class="token operator">==</span> CAMERA_DEVICE_API_VERSION_3_0 <span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">CAMSCOPE_INIT</span><span class="token punctuation">(</span>CAMSCOPE_SECTION_HAL<span class="token punctuation">)</span><span class="token punctuation">;</span>
    QCamera3HardwareInterface <span class="token operator">*</span>hw <span class="token operator">=</span> new <span class="token function">QCamera3HardwareInterface</span><span class="token punctuation">(</span>mHalDescriptors<span class="token punctuation">[</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">.</span>cameraId<span class="token punctuation">,</span> mCallbacks<span class="token punctuation">)</span><span class="token punctuation">;</span>

    rc <span class="token operator">=</span> hw<span class="token operator">-&gt;</span><span class="token function">openCamera</span><span class="token punctuation">(</span>hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

#ifdef QCAMERA_HAL1_SUPPORT
else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);

    rc <span class="token operator">=</span> hw<span class="token operator">-&gt;</span><span class="token function">openCamera</span><span class="token punctuation">(</span>hw_device<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

#endif
return rc;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

初始化 QCamera3HardwareInterface()

@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp
QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId, const camera_module_callbacks_t *callbacks)
    : mCameraId(cameraId),
      mCameraHandle(NULL),
      mCameraInitialized(false),
      mCallbacks(callbacks),
	...... //省略一系列Camera 初始化默认值
{
	// 1. 获取HAL 层 log 等级
    getLogLevel();
    =========>
    	property_get("persist.camera.hal.debug", prop, "0");
    	property_get("persist.camera.kpi.debug", prop, "0");
    	property_get("persist.camera.global.debug", prop, "0");
mCommon<span class="token punctuation">.</span><span class="token function">init</span><span class="token punctuation">(</span>gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>tag <span class="token operator">=</span> HARDWARE_DEVICE_TAG<span class="token punctuation">;</span>
mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>version <span class="token operator">=</span> CAMERA_DEVICE_API_VERSION_3_4<span class="token punctuation">;</span>

mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">.</span>close <span class="token operator">=</span> close_camera_device<span class="token punctuation">;</span>
mCameraDevice<span class="token punctuation">.</span>ops <span class="token operator">=</span> <span class="token operator">&amp;</span>mCameraOps<span class="token punctuation">;</span>
	<span class="token operator">==</span><span class="token operator">=</span>⇒ @ hardware<span class="token operator">/</span>qcom<span class="token operator">/</span>camera<span class="token operator">/</span>QCamera2<span class="token operator">/</span>HAL3<span class="token operator">/</span>QCamera3HWI<span class="token punctuation">.</span>cpp
mCameraDevice<span class="token punctuation">.</span>priv <span class="token operator">=</span> this<span class="token punctuation">;</span>
gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-&gt;</span>version <span class="token operator">=</span> CAM_HAL_V3<span class="token punctuation">;</span>

<span class="token comment">// TODO: hardcode for now until mctl add support for min_num_pp_bufs</span>
<span class="token comment">//TBD - To see if this hardcoding is needed. Check by printing if this is filled by mctl to 3</span>
gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-&gt;</span>min_num_pp_bufs <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
pthread_condattr_t mCondAttr<span class="token punctuation">;</span>

<span class="token function">pthread_condattr_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">pthread_condattr_setclock</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">,</span> CLOCK_MONOTONIC<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mBuffersCond<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mRequestCond<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">pthread_cond_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mHdrRequestCond<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">pthread_condattr_destroy</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mCondAttr<span class="token punctuation">)</span><span class="token punctuation">;</span>

mPendingLiveRequest <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
mCurrentRequestId <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token function">pthread_mutex_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mMutex<span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> CAMERA3_TEMPLATE_COUNT<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
    mDefaultMetadata<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>

<span class="token comment">// Getting system props of different kinds</span>
<span class="token keyword">char</span> prop<span class="token punctuation">[</span>PROPERTY_VALUE_MAX<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 获取 persist.camera.raw.dump,是否使能 RAW dump 功能</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.raw.dump"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mEnableRawDump <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 获取 persist.camera.hal3.force.hdr,是否使能 hdr 功能</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.hal3.force.hdr"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
mForceHdrSnapshot <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>mEnableRawDump<span class="token punctuation">)</span>
    <span class="token function">LOGD</span><span class="token punctuation">(</span><span class="token string">"Raw dump from Camera HAL enabled"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mInputStreamInfo<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mInputStreamInfo<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">memset</span><span class="token punctuation">(</span>mLdafCalib<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mLdafCalib<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.tnr.preview"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_bTnrPreview <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.swtnr.preview"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_bSwTnrPreview <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.tnr.video"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_bTnrVideo <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.avtimer.debug"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_debug_avtimer <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"AV timer enabled: %d"</span><span class="token punctuation">,</span> m_debug_avtimer<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">memset</span><span class="token punctuation">(</span>prop<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">property_get</span><span class="token punctuation">(</span><span class="token string">"persist.camera.cacmode.disable"</span><span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
m_cacModeDisabled <span class="token operator">=</span> <span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span><span class="token function">atoi</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>

mRdiModeFmt <span class="token operator">=</span> gCamCapability<span class="token punctuation">[</span>mCameraId<span class="token punctuation">]</span><span class="token operator">-&gt;</span>rdi_mode_stream_fmt<span class="token punctuation">;</span>
<span class="token comment">//Load and read GPU library.</span>
lib_surface_utils <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
LINK_get_surface_pixel_alignment <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
mSurfaceStridePadding <span class="token operator">=</span> CAM_PAD_TO_32<span class="token punctuation">;</span>
<span class="token comment">// 打开 libadreno_utils.so</span>
lib_surface_utils <span class="token operator">=</span> <span class="token function">dlopen</span><span class="token punctuation">(</span><span class="token string">"libadreno_utils.so"</span><span class="token punctuation">,</span> RTLD_NOW<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>lib_surface_utils<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token operator">*</span><span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">&amp;</span>LINK_get_surface_pixel_alignment <span class="token operator">=</span>
            <span class="token function">dlsym</span><span class="token punctuation">(</span>lib_surface_utils<span class="token punctuation">,</span> <span class="token string">"get_gpu_pixel_alignment"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
     <span class="token keyword">if</span> <span class="token punctuation">(</span>LINK_get_surface_pixel_alignment<span class="token punctuation">)</span> <span class="token punctuation">{</span>
         mSurfaceStridePadding <span class="token operator">=</span> <span class="token function">LINK_get_surface_pixel_alignment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
     <span class="token punctuation">}</span>
     <span class="token function">dlclose</span><span class="token punctuation">(</span>lib_surface_utils<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>gCamCapability<span class="token punctuation">[</span>cameraId<span class="token punctuation">]</span><span class="token operator">-&gt;</span>is_quadracfa_sensor<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"Sensor support Quadra CFA mode"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    m_bQuadraCfaSensor <span class="token operator">=</span> true<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

m_bQuadraCfaRequest <span class="token operator">=</span> false<span class="token punctuation">;</span>
m_bQuadraSizeConfigured <span class="token operator">=</span> false<span class="token punctuation">;</span>
<span class="token function">memset</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mStreamList<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>camera3_stream_configuration_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

接下来,调用 hw->openCamera(hw_device);

@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp

int QCamera3HardwareInterface::openCamera(struct hw_device_t hw_device)
{
if (mState != CLOSED) {
*hw_device = NULL;
return PERMISSION_DENIED;
}

mPerfLockMgr<span class="token punctuation">.</span><span class="token function">acquirePerfLock</span><span class="token punctuation">(</span>PERF_LOCK_OPEN_CAMERA<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: E PROFILE_OPEN_CAMERA camera id %d"</span><span class="token punctuation">,</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>

rc <span class="token operator">=</span> <span class="token function">openCamera</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token operator">*</span>hw_device <span class="token operator">=</span> <span class="token operator">&amp;</span>mCameraDevice<span class="token punctuation">.</span>common<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token operator">*</span>hw_device <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">LOGI</span><span class="token punctuation">(</span><span class="token string">"[KPI Perf]: X PROFILE_OPEN_CAMERA camera id %d, rc: %d"</span><span class="token punctuation">,</span> mCameraId<span class="token punctuation">,</span> rc<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mState <span class="token operator">=</span> OPENED<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

接下来调用 int QCamera3HardwareInterface::openCamera()

@ hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp
int QCamera3HardwareInterface::openCamera()
{
    KPI_ATRACE_CAMSCOPE_CALL(CAMSCOPE_HAL3_OPENCAMERA);
    if (mCameraHandle) {
        LOGE("Failure: Camera already opened");
        return ALREADY_EXISTS;
    }
rc <span class="token operator">=</span> QCameraFlash<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reserveFlashForCamera</span><span class="token punctuation">(</span>mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>rc <span class="token operator">&lt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">LOGE</span><span class="token punctuation">(</span><span class="token string">"Failed to reserve flash for camera id: %d"</span><span class="token punctuation">,</span>
            mCameraId<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> UNKNOWN_ERROR<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

rc <span class="token operator">=</span> <span class="token function">camera_open</span><span class="token punctuation">(</span><span class="token punctuation">(</span>uint8_t<span class="token punctuation">)</span>mCameraId<span class="token punctuation">,</span> <span class="token operator">&amp;</span>mCameraHandle<span class="token punctuation">)</span><span class="token punctuation">;</span>

rc <span class="token operator">=</span> mCameraHandle<span class="token operator">-&gt;</span>ops<span class="token operator">-&gt;</span><span class="token function">register_event_notify</span><span class="token punctuation">(</span>mCameraHandle<span class="token operator">-&gt;</span>camera_handle<span class="token punctuation">,</span> camEvtHandle<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">void</span> <span class="token operator">*</span><span class="token punctuation">)</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span>


mExifParams<span class="token punctuation">.</span>debug_params <span class="token operator">=</span> <span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t <span class="token operator">*</span><span class="token punctuation">)</span> malloc <span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>mExifParams<span class="token punctuation">.</span>debug_params<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">memset</span><span class="token punctuation">(</span>mExifParams<span class="token punctuation">.</span>debug_params<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mm_jpeg_debug_exif_params_t<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</s
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值