相关文章
- [Android O] Camera 服务启动流程简析
- [Android O] HAL3 之 Open Camera2 流程(零)—— 概览
- [Android O] HAL3 之 Open Camera2 流程(一)—— 从 App 到 CameraService
- [Android O] HAL3 之 Open Camera2 流程(二)—— 从 CameraService 到 HAL Service
- [Android O] HAL3 之 Open Camera2 流程(三,完结)—— 从 HAL Service 到 Camera HAL
从 Application
连接到 CameraService
,这涉及到 Android 架构中的三个层次:App 层,Framework 层,Runtime 层。
其中,App 层直接调用 Framework 层所封装的方法,而 Framework 层需要通过 Binder 远程调用 Runtime 中 CameraService
的函数。
这一部分主要的函数调用逻辑如下图所示。
下面开始分析相关代码。
App
关于应用这方面,我只是略懂一二,具体的实现就不管它了。
在 App 中,需要调用打开相机的接口,如下。
其中:
mCameraManager
是 CameraManager 类的实例。currentCameraId
则是需要打开的相机设备号。stateCallback
是 CameraDevice.StateCallback,是关于相机打开情况的相关回调。backgroundHandler
则是 StateCallback 需要调用的Handler
。
mCameraManager.openCamera(currentCameraId, stateCallback, backgroundHandler);
以上内容参考自掘金网的一篇文章。
Framework
CameraManager
文件路径:/frameworks/base/core/java/android/hardware/camera2/CameraManager.java
最初的入口就是 CameraManager 的 openCamera
方法。
但通过代码可以看到,它仅仅是调用了 openCameraForUid
方法。
@RequiresPermission(android.Manifest.permission.CAMERA)
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException {
openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);
}
下面的代码忽略掉了一些参数检查相关操作,最终主要调用了 openCameraDeviceUserAsync
方法。
public void openCameraForUid(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler,
int clientUid)
throws CameraAccessException {
/* Do something in*/
......
/* Do something out*/
openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);
}
分析下面的代码:
- 第 11~17 行,首先实例化一个 CameraDeviceImpl。值得注意的是,构造时传入了
CameraDevice.StateCallback
以及Handler
。 - 第 19 行,获取 CameraDeviceCallback 实例,这是提供给远端连接到 CameraDeviceImpl 的接口。
- 第 22~32 行,HAL3 中走的是这一部分逻辑,主要是从 CameraManagerGlobal 中获取 CameraService 的本地接口,通过它远端调用(采用 Binder 机制)
connectDevice
方法连接到相机设备。注意返回的cameraUser
实际上指向的是远端 CameraDeviceClient 的本地接口。 - 为了缩短篇幅,省略了捕获异常的相关代码。
- 第 56 行,将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理。
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Handler handler, final int uid)
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
synchronized (mLock) {
ICameraDeviceUser cameraUser = null;
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
new android.hardware.camera2.impl.CameraDeviceImpl(
cameraId,
callback,
handler,
characteristics,
mContext.getApplicationInfo().