前面幾篇主要分析的是android Camera API1.0的架構以及初始化流程,而google在android5.0(Lollipop)開始對Camera的架構進行了調整,爲了適應HAL3,新添加實現了CameraDeviceClient,而Camera API1.0已經被deprecated(即可能在更新的版本里會不支持此API).
接下來,我將會分如下幾篇文章來分析Camera2
android6.0源碼分析之Camera API2.0簡介
android6.0源碼分析之Camera2 HAL分析
android6.0源碼分析之Camera API2.0下的初始化流程分析
android6.0源碼分析之Camera API2.0下的Preview(預覽)流程分析
android6.0源碼分析之Camera API2.0下的Capture流程分析
android6.0源碼分析之Camera API2.0下的video流程分析
Camera API2.0的應用
1、Camera API2.0的架構圖
Camera API2.0下的Camera架構與API1.0有所區別,下面將給出Camera API2.0以及Camera HAL3.2+下的Camera的總體架構圖:
由圖可知,Java層要想與C++層的CameraService層進行通信,都是通過Java層的IPC Binder進制進行的,主要包括ICameraService.aidl以及ICameraDeviceUser.aidl兩個接口來實現,其會在Java層維護一個CameraDeviceImpl即Camera設備的代理,而CameraService以及CameraDeviceImpl的初始化會在此文的第二,第三節進行分析。而Java層對Camera的具體操作的操作流程大致爲,Java層通過Device代理髮送一個CaptureRequest,而C++層進行相應的處理,再調用相應的回調來通知Java相應的處理結果,並將相應的Capture數據保存在Surface Buffer裏,這樣Java層在回調函數中可以對數據進行相應的處理。而對於具體操作流程的分析,請參考文章開始時的Camera2相關文章的連接。
2、Java層的CameraService的實現和應用
從Camera API2開始,Camera的實現方式有所不同,最主要的區別是不再使用JNI來調用本地代碼,從而獲得本地CameraService,並實現其C/S模式的通信,而是直接在Java層通過Java層的IPC Binder機制來獲取Java層的CameraService的代理對象,從而直接在Java層獲取本地的CameraService與Camera Device進行相應的通信。
相應的代碼及目錄:
ICameraService.aidl:frameworks/base/core/java/android/hardware
CameraService.cpp:frameworks/av/services/camera/libcameraservice
CameraManager.java:frameworks/base/core/java/android/hardware/camera2
獲取CameraService的核心代碼如下:
//CameraManager.java
prvate void connectCameraServiceLocked(){
if(mCameraService != null)return;
//獲取Binder
IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
if(cameraServiceBinder == null){
return;
}
try{
cameraServiceBinder.linkToDeath(this,/*flags*/ 0);
}catch(RemoteException e){
return;
}
ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
//根據cameraServiceRaw 創建CameraService實例
ICameraService cameraService = CameraServiceDecorator.newInstance(cameraServiceRaw);
...
try{
//添加監聽
cameraService.addListener(this);
//賦值給mCameraService的全局變量
mCameraService = cameraService;
}catch(CameraRuntimeException e){
...
}
}
- 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
由代碼可知,通過Java層的Binder從ServiceManager裏獲取了一個Java層的CameraService實例,在打開Camera的流程中,會通過此CameraService(Native的CameraService)與Camera通信,而其中的通信通過ICameraDeviceUser來實現,接下來分析ICameraDeviceUser的實現。
3、ICameraDeviceUser.aidl的通信實現
Java層與C++ CameraService層之間的通信,通過封裝了一個CameraDeviceUser來實現,它只是在Java層使用了AIDL技術來實現Client,即在Java層維護了一個CameraDevice,這樣的好處是響應速度更快,因爲這樣不需要通過每次進入Native層來完成通信,而可以通過Java層的IPC Binder機制即可完成。即API2.0通過AIDL實現一個接口ICameraDeviceUser,從而在Java層維護一個Camera proxy,之後的通信都是通過此代理CameraDeviceImpl來實現。
相關代碼及目錄:
ICameraDeviceUser.aidl:frameworks/base/core/java/android/hardware/camera2
ICameraDeviceUser.cpp:frameworks/av/camera/camera2
CameraDeviceImpl.java:frameworks/base/core/java/android/hardware/camera2/impl
獲取Camera Device的Java層代理的核心代碼如下:
//CameraManager.java
private CameraDevice openCameraDeviceUserAsync(...){
//初始化Camera Java層代理對象
CameraDevice device = null;
try{
synchronized(mLock){
//初始化ICameraDeviceUser
ICameraDeviceUser cameraUser = null;
//初始化具體的CameraDevice代理
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl = new android.hardware.
camera2.impl.CameraDeviceImpl(cameraId,callback,handler,characteristics);
BinderHolder holder = new BinderHolder();
ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
...
try{
//如果支持HAL3.2+的devices
if(supportsCamera2ApiLocked(cameraId)){
//獲取CameraService
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
...
//連接設備
cameraService.connectDevice(callbacks,id,mContextgetOpPackageName()
,USE_CALLING_UID,holder);
//通過Binder獲得打開的Camera設備返回的Camera代理
cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
}else{//否則用遺產API
cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks,id);
}
}catch(...){
...
}
//包裝代理對象
deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;
}
}catch(...){
...
}
返回Camera代理
return device;
}
- 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
由代碼可知,首先獲取CameraService,然後通過它來開啓Camera,而開啓成功後,C++層會返回一個Camera device代理對象,此處即爲ICameraDeviceUser,所以在Java層對其進行相應的封裝,變成一個CameraDeviceImpl對象,此後,只要需要對Camera進行操作,都會調用CameraDeviceImpl對象的相關方法,並通過ICameraDeviceUser以及Java IPC Binder來與本地的Camera device進行通信,至此,Camera API2.0的框架就分析結束了,具體的操作,如Camera的初始化,preview,capture等流程的分析,請看文章開始時,所列出的分析鏈接。
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
</div>