Android Camera Subsystem 架构(Binder机制)及显示分析

1 Camera Architecture (Binder机制应用)

该部分主要借助Camera Subsystem分享自己对binder的理解。对该部分的阅读不需要太多对Camera子系统的了解,结合大体类图,顺着我的思路也可以学习binder设计思想。通过我个人的一个思考路线,来阐述如何将binder通信机制嵌入到一个Subsystem中。通过这部分的启发,可以帮助大家应用binder通信机制,可以为Android Framwork开发更多的服务。也希望大家在阅读的时候,给我一些指导,同时帮助我更深的理解Android。大家看到的结构图和类图,我会尽快更新,因为这两个图是我大概在三个月之前刚接触项目,大概浏览下源码简单了解结构之后画的,大体方向没有错误,但是缺少一些细节,最近工作比较忙,没来的及更新。项目release之后我会添加详细结构图及类图。

2 Camera Display

该部分主要是结合自己对Camera Subsystem中涉及的Display的一个分析,帮助大家尽快理解Camera Subsystem。对这块的理解需要一些Android基础知识和Camera Subsystem源码基础。代码可能和你看到的源码不是很一样,因为已经是修改过的,包括Capture和Recording都可以很健壮的运行,而且已经过严格测试。

1、Camera Architecture

(1)Camera Architecture


(2)Camera File

 

          

 

 (3)Camera Framework

 

 

 

上面的类图只是一个简单的继承关系,并没有体现出很多细节,只供大家参考。ICamera、ICameraClient、ICameraServices三个类是按照Binder IPC要求的框架实现的。类Camera与CameraService端通过Binder IPC机制来实现具体的功能。 Camera类通过getCameraService()向ServiceManager发出请求,得到了一个名字为“media.camera”的CameraService实例。 通过调用CameraService提供的接口connect()在CameraService端new一个CameraService::Client类的对象mClient,通过connect将该对对象返回给Camera Client端 。随后Camera通过这个sp<ICamera> mCamera对象调用函数就如同直接调用CameraService::Client类的函数。 CameraService::Client 在CameraService内部真正处理由Camera Client发往Camera Service的请求和由 Camera  HAL返回的数据及notify信息。其中之前的callback函数和Camera HAL都以成员变量的形式存在于 class Client。



但是要问,这样一种组织如何将binder引入其中呢,这么多接口又是如何组织的?

首先,如果是我们自己一旦确定使用C/S架构。那么我们肯定会至少定义两个类,一个是Client类,一个是Server类。哪如何实现Client与Server之间的交互呢,或者通信呢?不用问肯定想到了网络通信Socket。因为很多时候大家只要提到Client和Server,第一本能好像就会联想到网络通信Socket,其实这个本能害人不小,让你失去了很多了解真相的机会。我们学过最基本的IPC能叫得上名字的至少有6种,其中socket只是其中的一种,也可以说socket是网络环境下最常用的一种通信方式。如果你了解linux内核,你就会知道socket的用处绝不仅限于此。说到底双方只要达到对消息结构的一致解释,就可以实现通信,完成相应的功能需求。那如果我告诉你,Client端和Server端运行在同一台机器上,使用同一根内存条。我们是不是又本能的想到了共享内存呢,这会你怎么没想到socket呢?我们能不能使用本地socket呢?其实Android中很多系统服务就是利用的本地socket来实现进程通信,通过在init的时候创建,然后在模块启动之后直接引用,因为socket无非就对应着本地文件么,创建了之后就放在那里。例如vold中就充分利用了socket。当然本地Socket、共享内存只是我们众多备选方案中最常用的两种。每次谈到IPC,很多人都觉得很难懂。其实很多时候是我们自己理解复杂了,将能用鼠标点到和眼睛看到的东西掉入了内存,就觉得摸不到了,结果给自己设置了一些障碍。举个例子,不考虑时间,最通俗的方法,你在随手建的文件夹test中写一个带main函数的程序,通过该程序在当前目录下创建并写了一个文件;随后你又在同一个目录下又创建了另一个带main函数的程序,执行该程序去访问先前程序创建的文件,你对文件又做了修改。这样两个进程实际上就实现了通信,你觉得这很容易理解,因为你将自己的思维定格在了这个test文件夹中,你能不能更深更远的拓展一下这种思维呢。而为让这种通信得到有效的保证,随后我们又提出同步,锁机制等等。

言归正传,一个进程和另一个进程要交换数据,或者要协同工作,抽象到程序上来说就是类与类之间的引用关系,函数之间的调用关系。我自己将其分为两类,一种是采用依赖调用的方式,另一种是消息机制。我在这里要说的意思是,通信双方要不要为对方提供完整的调用接口。如果我是采用依赖调用,我得知道我能调用你那些方法,这样就必须为调用者提供完整的调用接口;如果采用消息解析,我得知道我能发送那些消息或者命令,至于你能对这些命令做出符合协议规定的动作那是你的事,我只需要结果,那至少要维护一个命令接收和命令处理的状态机。两者的实质是一样,其实依赖调用按照面向对象来说也是一种消息机制。如果是依赖调用,那我们就必须提供一定的权限和完整的结构供对方调用。最基本的:如果是C函数,那你就不能把供别人调用的方法在实现文件中定义为static;如果是C++,那你就不能把它定义为private,protected(protected其实还说的过去,至少自己人可以访问)。如果是消息,我们得看看你响应的命令集或消息结构。

我第一次拿到Camera Subsystem的时候,就被从网上看到的这句话给蒙住了“ICamera/ICameraClient/ICameraServices三个类是按照Binder IPC要求的框架实现的”。我要问,到底是按什么框架要求实现的?我知道它的Client端和Service端用了Binder通信机制,但我一直捉摸不透,这个框架它为什么要求定义那么多接口,还有那么多所谓的Proxy Class和Native Class,还相互继承来继承去的。后来我总算明白了一点,他们是用了一些设计模式才会弄得这么复杂,给自己看不懂找点借口。后来我对自己产生怀疑,我问自己仅仅是设计模式的原因吗,你真的懂细节吗?我发现我还一时回答不了这个问题,我觉得还是我没搞清楚这些结构定义的目的和他们之间的调用关系。

回到Android的Binder。至少在Camera Subsystem中来看Binder通信。用我自己的理解,Binder通信机制正好是结合了依赖调用和消息机制。ICamera、ICameraClient、ICameraService为Camera Client端和Camera Service端之间的交互提供了完备的接口,这样实现了他们之间的相互调用,而隐含在这些接口下面的却是一块共享内存,这块共享内从由上层的ProcessState和IPCThreadState和内核的Binder Driver来管理。而Binder中的transact和OnTransact方法就分别对应着命令接收器和命令处理器。

再看Camera Subsystem。首先,如果不考虑Camera HAL层,在Camera Subsystem Native层存在三个主要对象:一个是充当Camera Client的Camera类;一个是充当Camera Server的CameraService类;还有另一个无名英雄类CameraService::Client类,说它是无名英雄,一点都不过分,它几乎干了CameraService的所有事情,也可以认为CameraService是个高明的管理者,它善于放权,把一切都交给CameraService::Client类来处理。如果是我,我肯定不会设计出CameraService::Client这个类来,我肯定是CameraService包揽一起,因为我还不懂得功能细化,最主要的原因是我还没有足够的经验和能力设计出它。首先站在Client的角度,要完成两件事,

一是与Server端建立连接,我自己都克制不住socket的思想又冒出来了,其实很简单,我们只要new 一个Client对象,把这个对象赋值给Server端内部维护的Client指针,同时在new一个Server对象,赋值给Client端内部的Server指针,只要双方能够彼此引用,那么连接就已经建立起来了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值