2.3camera service的connectDevice的過程

在上一節中,我們梳理了camera open在framework中涉及的類和它們的主要功能,但是我們跳過了一些關鍵的細節,所以在這一章節中,我們將首先來分析connectDevice的過程。

首先我們來看在ICameraService.aidl中的定義,

接口定義了四個變量callbacks、設備id、應用的包名、clientUid,如果是從openCamera方法調用的,這裏就是-1。

       然後我們到接口實現CameraService.h中查看。

除了接口定義的四個參數,還多出了一個out的device,類型是ICameraDeviceUser,這剛好與上一節中的返回值一致。

connectDevice方法的核心就是調用了connectHelper方法。首先調用validateConnectLocked方法判斷設備是否可用。

判斷的過程是首先判斷是否已經初始化mInitialized,這個值是在啓動CameraService時調用onFirstRef方法賦值的。

然後判斷CameraState是否爲空,CameraState內部實現了CameraParameters的get、set方法。如果不爲空,那麼通過取得的cameraState對象就能夠得到CameraParameters,從而得到相機各種size相關的參數,例如fps range、preview sizes、video sizes等。

最後判斷相機是否已經被佔用,如果對應camera id的相機正常就返回狀態NO_ERROR。

connectHelper方法接下來會判斷shim parameter的更新狀態,connectDevice直接傳入了false,所以這裏可以不用關注。

之後就該執行handleEvictionsLocked方法,這個方法很重要,是進行相機多進程互斥邏輯的方法。多個應用無法同時打開相機就是在這個方法中進行管理的。在下一章節中,我們單獨對這個地方進行分析。

接下來對兩個特殊情況進行處理。由於API1的MediaRecoder會返回一個client,所以對MediaRecoder不爲空的情況做一個單獨的處理。

       相機打開的情況下,閃光燈的控制必須交由相機控制,所以此時會關閉所有閃光燈的控制,如果手電筒打開,就會在此時被關閉。

       然後就進入了真正的client流程,先通過getDeviceVersion方法取得對應底層HAL的版本,這裏的版本與HAL本身的版本略有不同。作用是根據版本的不同確定HAL中的小版本,各個版本的區別是庫中方法有所不同。根據Device version調用makeClient方法創建Camera Client對象。

makeClient方法主要有兩個操作,1是判斷API+HAL版本的通路; 2是根據判定結果決定創建哪個client。client類有三個,分別是CameraClient、Camera2Client和CameraDeviceClient。

具體對應關係是:

API1+HAL3->CameraClient

API1+HAL3->Camera2Client

API2+HAL3->CameraDeviceClient

得到client之後就是進行真正的Camera打開的操作了。

核心就是調用client的initalize方法,這個方法傳入了CameraProviderManager對象作爲參數,我們前文介紹過,CameraService並不是直接與底層通信,而是通過Provider進程進行的。而CameraProviderManager就是CameraService持有的Provider的manager。通過一系列initalize方法和initalizeImpl方法的調用,最終通過打開相機。

 

 

 

 

 

發佈了87 篇原創文章 · 獲贊 13 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章