android6.0源码分析之Camera API2.0简介
1、Camera API2.0的架構(gòu)圖
Camera API2.0下的Camera架構(gòu)與API1.0有所區(qū)別,下面將給出Camera API2.0以及Camera HAL3.2+下的Camera的總體架構(gòu)圖:?
?
由圖可知,Java層要想與C++層的CameraService層進行通信,都是通過Java層的IPC Binder進制進行的,主要包括ICameraService.aidl以及ICameraDeviceUser.aidl兩個接口來實現(xiàn),其會在Java層維護一個CameraDeviceImpl即Camera設(shè)備的代理,而CameraService以及CameraDeviceImpl的初始化會在此文的第二,第三節(jié)進行分析。而Java層對Camera的具體操作的操作流程大致為,Java層通過Device代理發(fā)送一個CaptureRequest,而C++層進行相應(yīng)的處理,再調(diào)用相應(yīng)的回調(diào)來通知Java相應(yīng)的處理結(jié)果,并將相應(yīng)的Capture數(shù)據(jù)保存在Surface Buffer里,這樣Java層在回調(diào)函數(shù)中可以對數(shù)據(jù)進行相應(yīng)的處理。而對于具體操作流程的分析,請參考文章開始時的Camera2相關(guān)文章的連接。
2、Java層的CameraService的實現(xiàn)和應(yīng)用
從Camera API2開始,Camera的實現(xiàn)方式有所不同,最主要的區(qū)別是不再使用JNI來調(diào)用本地代碼,從而獲得本地CameraService,并實現(xiàn)其C/S模式的通信,而是直接在Java層通過Java層的IPC Binder機制來獲取Java層的CameraService的代理對象,從而直接在Java層獲取本地的CameraService與Camera Device進行相應(yīng)的通信。?
相應(yīng)的代碼及目錄:?
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的核心代碼如下:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//CameraManager.java prvate void connectCameraServiceLocked(){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(mCameraService != null)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;//獲取BinderIBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(cameraServiceBinder == null){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{cameraServiceBinder.linkToDeath(this,/*flags*/ <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);}catch(RemoteException e){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);//根據(jù)cameraServiceRaw 創(chuàng)建CameraService實例ICameraService cameraService = CameraServiceDecorator.newInstance(cameraServiceRaw);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{//添加監(jiān)聽cameraService.addListener(this);//賦值給mCameraService的全局變量mCameraService = cameraService;}catch(CameraRuntimeException e){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul>由代碼可知,通過Java層的Binder從ServiceManager里獲取了一個Java層的CameraService實例,在打開Camera的流程中,會通過此CameraService(Native的CameraService)與Camera通信,而其中的通信通過ICameraDeviceUser來實現(xiàn),接下來分析ICameraDeviceUser的實現(xiàn)。
3、ICameraDeviceUser.aidl的通信實現(xiàn)
Java層與C++ CameraService層之間的通信,通過封裝了一個CameraDeviceUser來實現(xiàn),它只是在Java層使用了AIDL技術(shù)來實現(xiàn)Client,即在Java層維護了一個CameraDevice,這樣的好處是響應(yīng)速度更快,因為這樣不需要通過每次進入Native層來完成通信,而可以通過Java層的IPC Binder機制即可完成。即API2.0通過AIDL實現(xiàn)一個接口ICameraDeviceUser,從而在Java層維護一個Camera proxy,之后的通信都是通過此代理CameraDeviceImpl來實現(xiàn)。
相關(guān)代碼及目錄:?
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層代理的核心代碼如下:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//CameraManager.java private CameraDevice openCameraDeviceUserAsync(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>){//初始化Camera Java層代理對象CameraDevice device = null;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{synchronized(mLock){//初始化ICameraDeviceUserICameraDeviceUser 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();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{//如果支持HAL3.2+的devices<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(supportsCamera2ApiLocked(cameraId)){//獲取CameraServiceICameraService cameraService = CameraManagerGlobal.get().getCameraService();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//連接設(shè)備cameraService.connectDevice(callbacks,id,mContextgetOpPackageName(),USE_CALLING_UID,holder);//通過Binder獲得打開的Camera設(shè)備返回的Camera代理cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{//否則用遺產(chǎn)APIcameraUser = CameraDeviceUserShim.connectBinderShim(callbacks,id);}}catch(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>}//包裝代理對象deviceImpl.setRemoteDevice(cameraUser);device = deviceImpl;}}catch(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>}返回Camera代理<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> device; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li></ul>由代碼可知,首先獲取CameraService,然后通過它來開啟Camera,而開啟成功后,C++層會返回一個Camera device代理對象,此處即為ICameraDeviceUser,所以在Java層對其進行相應(yīng)的封裝,變成一個CameraDeviceImpl對象,此后,只要需要對Camera進行操作,都會調(diào)用CameraDeviceImpl對象的相關(guān)方法,并通過ICameraDeviceUser以及Java IPC Binder來與本地的Camera device進行通信,至此,Camera API2.0的框架就分析結(jié)束了,具體的操作,如Camera的初始化,preview,capture等流程的分析,請看文章開始時,所列出的分析鏈接。
原文地址:?http://blog.csdn.net/yangzhihuiguming/article/details/51382267
總結(jié)
以上是生活随笔為你收集整理的android6.0源码分析之Camera API2.0简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Framework系统服
- 下一篇: android6.0源码分析之Camer