1. SurfaceControl的来历
根据精简的流程可知,这一节要分析的是SurfaceControl对象。先回顾一下这个对象的创建过程,代码如下所示:
**android_view_Surface.cpp**
~~~
static void Surface_init(JNIEnv* env, jobjectclazz, jobject session,
jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags)
{
SurfaceComposerClient* client =
(SurfaceComposerClient*)env->GetIntField(session, sso.client);
//注意这个变量,类型是SurfaceControl,名字却叫surface,稍不留神就出错了。
sp<SurfaceControl>surface;
if (jname == NULL) {
//调用Client的createSurface函数,得到一个SurfaceControl对象。
surface= client->createSurface(pid, dpy, w, h, format, flags);
}
......
//将这个SurfaceControl对象设置到Java层的对象中保存。
setSurfaceControl(env, clazz, surface);
}
~~~
通过上面的代码可知,SurfaceControl对象由createSurface得来,下面看看这个函数。
此时,读者或许会被代码中随意起的变量名搞糊涂,因为我的处理方法碰到了容易混淆的地方,尽量以对象类型来表示这个对象。
(1)分析createSurface的请求端
在createSurface内部会使用Binder通信将请求发给SF,所以它分为请求和响应两端,先看请求端,代码如下所示:
**SurfaceComposerClient.cpp**
~~~
sp<SurfaceControl>SurfaceComposerClient::createSurface(
int pid,
DisplayID display,//DisplayID是什么意思?
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
String8 name;
constsize_t SIZE = 128;
charbuffer[SIZE];
snprintf(buffer, SIZE, "<pid_%d>", getpid());
name.append(buffer);
//调用另外一个createSurface,多一个name参数
returnSurfaceComposerClient::createSurface(pid, name, display,
w, h, format, flags);
}
~~~
在分析另外一个createSurface之前,应先介绍一下DisplayID的含义:
~~~
typedef int32_t DisplayID;
~~~
DisplayID是一个int整型,它的意义是屏幕编号,例如双屏手机就有内屏和外屏两块屏幕。由于目前Android的Surface系统只支持一块屏幕,所以这个变量的取值都是0。
再分析另外一个createSurface函数,它的代码如下所示:
**SurfaceComposerClient.cpp**
~~~
sp<SurfaceControl>SurfaceComposerClient::createSurface(
int pid,const String8& name,DisplayID display,uint32_t w,
uint32_t h,PixelFormat format,uint32_t flags)
{
sp<SurfaceControl> result;
if(mStatus == NO_ERROR) {
ISurfaceFlingerClient::surface_data_t data;
//调用BpSurfaceFlingerClient的createSurface函数
sp<ISurface> surface = mClient->createSurface(&data, pid,name,
display, w, h,format, flags);
if(surface != 0) {
if (uint32_t(data.token) < NUM_LAYERS_MAX) {
//以返回的ISurface对象创建一个SurfaceControl对象
result = new SurfaceControl(this, surface, data, w, h,
format, flags);
}
}
}
returnresult;//返回的是SurfaceControl对象
}
~~~
请求端的处理比较简单:
- 调用跨进程的createSurface函数,得到一个ISurface对象,根据Binder一章的知识可知,这个对象的真实类型是BpSurface。不过以后统称之为ISurface。
- 以这个ISurface对象为参数,构造一个SurfaceControl对象。
createSurface函数的响应端在SurfaceFlinger进程中,下面去看这个函数。
在Surface系统定义了很多类型,咱们也中途休息一下,不妨来看看和字符串“Surface”有关的有多少个类,权当其为小小的
娱乐:
Native层有Surface、ISurface、SurfaceControl、SurfaceComposerClient。
Java层有Surface、SurfaceSession。
上面列出的还只是一部分,后面还有呢!*&@&*%¥*
(2)分析createSurface的响应端
前面讲过,可把BClient看作是SF的Proxy,它会把来自客户端的请求派发给SF处理,通过代码来看看,是不是这样的?如下所示:
**SurfaceFlinger.cpp**
~~~
sp<ISurface> BClient::createSurface(
ISurfaceFlingerClient::surface_data_t* params, int pid,
const String8& name,
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
//果然是交给SF处理,以后我们将跳过BClient这个代理。
return mFlinger->createSurface(mId, pid,name, params, display, w, h,
format, flags);
}
~~~
来看createSurface函数,它的目的就是创建一个ISurface对象,不过这中间的玄机还挺多,代码如下所示:
**SurfaceFlinger.cpp**
~~~
sp<ISurface>SurfaceFlinger::createSurface(ClientID clientId, int pid,
const String8& name, ISurfaceFlingerClient::surface_data_t* params,
DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
sp<LayerBaseClient> layer;//LayerBaseClient是Layer家族的基类
//这里又冒出一个LayerBaseClient的内部类,它也叫Surface,是不是有点头晕了?
sp<LayerBaseClient::Surface> surfaceHandle;
Mutex::Autolock _l(mStateLock);
//根据clientId找到createConnection时加入的那个Client对象
sp<Client> client = mClientsMap.valueFor(clientId);
......
//注意这个id,它的值表示Client创建的是第几个显示层,根据图8-14可以看出,这个id
//同时也表示将使用SharedBufferStatck数组的第id个元素。
int32_t id = client->generateId(pid);
//一个Client不能创建多于NUM_LAYERS_MAX个的Layer。
if(uint32_t(id) >= NUM_LAYERS_MAX) {
return surfaceHandle;
}
//根据flags参数来创建不同类型的显示层,我们在8.4.1节介绍过相关知识
switch(flags & eFXSurfaceMask) {
case eFXSurfaceNormal:
if (UNLIKELY(flags & ePushBuffers)) {
//创建PushBuffer类型的显示层,我们将在拓展思考部分分析它
layer = createPushBuffersSurfaceLocked(client, d, id,
w, h, flags);
} else {
//①创建Normal类型的显示层,我们分析待会这个
layer = createNormalSurfaceLocked(client, d, id,
w, h, flags, format);
}
break;
case eFXSurfaceBlur:
//创建Blur类型的显示层
layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
break;
case eFXSurfaceDim:
//创建Dim类型的显示层
layer = createDimSurfaceLocked(client, d, id, w, h, flags);
break;
}
if(layer != 0) {
layer->setName(name);
setTransactionFlags(eTransactionNeeded);
//从显示层对象中取出一个ISurface对象赋值给SurfaceHandle
surfaceHandle = layer->getSurface();
if(surfaceHandle != 0) {
params->token = surfaceHandle->getToken();
params->identity = surfaceHandle->getIdentity();
params->width = w;
params->height = h;
params->format = format;
}
}
returnsurfaceHandle;//ISurface的Bn端就是这个对象。
}
~~~
上面代码中的函数倒是很简单,知识代码里面冒出来的几个新类型和它们的名字却让人有点头晕。先用文字总结一下:
- LayerBaseClient:前面提到的显示层在代码中的对应物,就是这个LayerBaseClient,不过这是一个大家族,不同类型的显示层将创建不同类型的LayerBaseClient。
- LayerBaseClient中有一个内部类,名字叫Surface,这是一个支持Binder通信的类,它派生于ISurface。
关于Layer的故事,后面会有单独的章节来介绍。这里先继续分析createNormalSurfaceLocked函数。它的代码如下所示:
**SurfaceFlinger.cpp**
~~~
sp<LayerBaseClient>SurfaceFlinger::createNormalSurfaceLocked(
const sp<Client>& client, DisplayID display,
int32_t id, uint32_t w, uint32_t h, uint32_t flags,
PixelFormat& format)
{
switch(format) { //一些图像方面的参数设置,可以不去管它。
casePIXEL_FORMAT_TRANSPARENT:
casePIXEL_FORMAT_TRANSLUCENT:
format = PIXEL_FORMAT_RGBA_8888;
break;
casePIXEL_FORMAT_OPAQUE:
format = PIXEL_FORMAT_RGB_565;
break;
}
//①创建一个Layer类型的对象
sp<Layer> layer = new Layer(this, display,client, id);
//②设置Buffer
status_t err = layer->setBuffers(w, h, format, flags);
if (LIKELY(err == NO_ERROR)) {
//初始化这个新layer的一些状态
layer->initStates(w, h, flags);
//③ 还记得在图8-10中提到的Z轴吗?下面这个函数把这个layer加入到Z轴大军中。
addLayer_l(layer);
}
......
returnlayer;
}
~~~
createNormalSurfaceLocked函数有三个关键点,它们是:
- 构造一个Layer对象。
- 调用Layer对象的setBuffers函数。
- 调用SF的addLayer_l函数。
暂且记住这三个关键点,后文有单独章节分析它们。先继续分析SurfaceControl的流程。
(3)创建SurfaceControl对象
当跨进程的createSurface调用返回一个ISurface对象时,将通过下面的代码创建一个SurfaceControl对象:
~~~
result = new SurfaceControl(this, surface, data,w, h,format, flags);
~~~
下面来看这个SurfaceControl对象为何物。它的代码如下所示:
**SurfaceControl.cpp**
~~~
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
const ISurfaceFlingerClient::surface_data_t& data,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
//mClient为SurfaceComposerClient,而mSurface指向跨进程createSurface调用
//返回的ISurface对象。
:mClient(client), mSurface(surface),
mToken(data.token), mIdentity(data.identity),
mWidth(data.width), mHeight(data.height), mFormat(data.format),
mFlags(flags)
{
}
~~~
SurfaceControl类可以看作是一个wrapper类:
它封装了一些函数,通过这些函数可以方便地调用mClient或ISurface提供的函数。
在SurfaceControl的分析过程中,还遗留了和Layer相关的部分,下面就来解决它们。
2. Layer和它的家族
我们在createSurface中创建的是Normal的Layer,下面先看这个Layer的构造函数。
(1)Layer的构造
Layer是从LayerBaseClient派生的,其代码如下所示:
**Layer.cpp**
~~~
Layer::Layer(SurfaceFlinger* flinger, DisplayIDdisplay,
const sp<Client>& c, int32_t i)//这个i表示SharedBufferStack数组的索引
: LayerBaseClient(flinger, display, c, i),//先调用基类构造函数
mSecure(false),
mNoEGLImageForSwBuffers(false),
mNeedsBlending(true),
mNeedsDithering(false)
{
//getFrontBuffer实际取出的是FrontBuffer的位置
mFrontBufferIndex = lcblk->getFrontBuffer();
}
~~~
再来看基类LayerBaseClient的构造函数,代码如下所示:
**LayerBaseClient.cpp**
~~~
LayerBaseClient::LayerBaseClient(SurfaceFlinger*flinger, DisplayID display,
const sp<Client>& client, int32_t i)
:LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
/*
创建一个SharedBufferServer对象,注意它使用了SharedClient对象,
并且传入了表示SharedBufferStack数组索引的i和一个常量NUM_BUFFERS
*/
lcblk = new SharedBufferServer(
client->ctrlblk, i, NUM_BUFFERS,//该值为常量2,在Layer.h中定义
mIdentity);
}
~~~
SharedBufferServer是什么?它和SharedClient有什么关系?
其实,之前在介绍SharedClient时曾提过与此相关的内容,这里再来认识一下,先看图8-15:
:-: ![](http://img.blog.csdn.net/20150802162659551?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-15 ShardBufferServer的示意图
根据上图并结合前面的介绍,可以得出以下结论:
- 在SF进程中,Client的一个Layer将使用SharedBufferStack数组中的一个成员,并通过SharedBufferServer结构来控制这个成员,我们知道SF是消费者,所以可由SharedBufferServer来控制数据的读取。
- 与之相对应,客户端的进程也会有一个对象来使用这个SharedBufferStatck,可它是通过另外一个叫SharedBufferClient的结构来控制的。客户端为SF提供数据,所以可由SharedBufferClient控制数据的写入。在后文的分析中还会碰到SharedBufferClient。
注意,在拓展思考部分,会有单独章节来分析生产/消费过程中的读写控制。
通过前面的代码可知,Layer对象被new出来后,传给了一个sp对象,读者还记得sp中的onFirstRef函数吗?Layer家族在这个函数中还有一些处理。一起去看看,但这个函数由基类LayerBaseClient实现。
**LayerBase.cpp**
~~~
void LayerBaseClient::onFirstRef()
{
sp<Client> client(this->client.promote());
if (client != 0) {
//把自己加入client对象的mLayers数组中,这部分内容比较简单,读者可以自行研究
client->bindLayer(this, mIndex);
}
}
~~~
好,Layer创建完毕,下面来看第二个重要的函数setBuffers。
(2)setBuffers的分析
setBuffers,Layer类以及Layer的基类都有实现。由于创建的是Layer类型的对象,所以请读者直接到Layer.cpp中寻找setBuffers函数。这个函数的目的就是创建用于PageFlipping的FrontBuffer和BackBuffer。一起来看,代码如下所示:
**Layer.cpp**
~~~
status_t Layer::setBuffers( uint32_t w, uint32_th,
PixelFormat format,uint32_t flags)
{
PixelFormatInfo info;
status_t err = getPixelFormatInfo(format, &info);
if(err) return err;
//DisplayHardware是代表显示设备的HAL对象,0代表第一块屏幕的显示设备。
//这里将从HAL中取出一些和显示相关的信息。
constDisplayHardware& hw(graphicPlane(0).displayHardware());
uint32_t const maxSurfaceDims = min(
hw.getMaxTextureSize(), hw.getMaxViewportDims());
PixelFormatInfo displayInfo;
getPixelFormatInfo(hw.getFormat(),&displayInfo);
constuint32_t hwFlags = hw.getFlags();
......
/*
创建Buffer,这里将创建两个GraphicBuffer。这两个GraphicBuffer就是我们前面
所说的FrontBuffer和BackBuffer。
*/
for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
//注意,这里调用的是GraphicBuffer的无参构造函数,mBuffers是一个二元数组。
mBuffers[i] = new GraphicBuffer();
}
//又冒出来一个SurfaceLayer类型,#¥%……&*!@
mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
returnNO_ERROR;
}
~~~
setBuffers函数的工作内容比较简单,就是:
- 创建一个GraphicBuffer缓冲数组,元素个数为2,即FrontBuffer和BackBuffer。
- 创建一个SurfaceLayer,关于它的身世我们后续再介绍。
GraphicBuffer是Android提供的显示内存管理类,关于它的故事,将在8.4.7节中介绍。我们暂把它当做普通的Buffer即可。
setBuffers中出现的SurfaceLayer类是什么?读者可能对此感觉有些晕乎。待把最后一个关键函数addLayer_l介绍完,或许就不太晕了。
(3)addLayer_l的分析
addLayer_l把这个新创建的layer加入自己的Z轴大军,下面来看:
**SurfaceFlinger.cpp**
~~~
status_t SurfaceFlinger::addLayer_l(constsp<LayerBase>& layer)
{
/*
mCurrentState是SurfaceFlinger定义的一个结构,它有一个成员变量叫
layersSortedByZ,其实就是一个排序数组。下面这个add函数将把这个新的layer按照
它在Z轴的位置加入到排序数组中。mCurrentState保存了所有的显示层。
*/
ssize_t i = mCurrentState.layersSortedByZ.add(
layer,&LayerBase::compareCurrentStateZ);
sp<LayerBaseClient> lbc =
LayerBase::dynamicCast< LayerBaseClient*>(layer.get());
if(lbc != 0) {
mLayerMap.add(lbc->serverIndex(), lbc);
}
returnNO_ERROR;
}
~~~
对Layer的三个关键函数都已分析过了,下面正式介绍Layer家族。
(4)Layer家族的介绍
前面的内容确让人头晕眼花,现在应该帮大家恢复清晰的头脑。先来“一剂猛药”,见图8-16:
:-: ![](http://img.blog.csdn.net/20150802162717491?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-16 Layer家族
通过上图可知:
- LayerBaseClient从LayerBase类派生。
- LayerBaseClient还有四个派生类,分别是Layer、LayerBuffer、LayerDim和LayerBlur。
- LayerBaseClient定义了一个内部类Surface,这个Surface从ISurface类派生,它支持Binder通信。
- 针对不同的类型,Layer和LayerBuffer分别有一个内部类SurfaceLayer和SurfaceLayerBuffer,它们继承了LayerBaseClient的Surface类。所以对于Normal类型的显示层来说,getSurface返回的ISurface对象的真正类型是SurfaceLayer。
- LayerDim和LayerBlur类没有定义自己的内部类,所以对于这两种类型的显示层来说,它们直接使用了LayerBaseClient的Surface。
- ISurface接口提供了非常简单的函数,如requestBuffer、postBuffer等。
这里大量使用了内部类。我们知道,内部类最终都会把请求派发给外部类对象来处理,既然如此,在以后分析中,如果没有特殊情况,就会直接跳到外部类的处理函数中。
强烈建议Google把Surface相关代码好好整理一下,至少让类型名取得更直观些,现在这样确实有点让人头晕。好,来小小娱乐一下。看之前介绍的和“Surface”有关的名字:
Native层有Surface、ISurface、SurfaceControl、SurfaceComposerClient。
Java层有Surface、SurfaceSession。
在介绍完Layer家族后,与它相关的名字又多了几个,它们是
LayerBaseClient::Surface、Layer::SurfaceLayer、LayerBuffer::SurfaceLayerBuffer。
3. SurfaceControl总结
SurfaceControl创建后得到了什么呢?可用图8-17来表示:
:-: ![](http://img.blog.csdn.net/20150802162734012?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图8-17 SurfaceControl创建后的结果图
通过上图可以知道:
- mClient成员变量指向SurfaceComposerClient。
- mSurface的Binder通信响应端为SurfaceLayer。
- SurfaceLayer有一个变量mOwner指向它的外部类Layer,而Layer有一个成员变量mSurface指向SurfaceLayer。这个SurfaceLayer对象由getSurface函数返回。
>[info] **注意**,mOwner变量由SurfaceLayer的基类Surface(LayBaseClient的内部类)定义。
接下来就是writeToParcel分析和Native Surface对象的创建了。注意,这个Native的Surface可不是LayBaseClient的内部类Surface。
- 前言
- 第1章 阅读前的准备工作
- 1.1 系统架构
- 1.1.1 Android系统架构
- 1.1.2 本书的架构
- 1.2 搭建开发环境
- 1.2.1 下载源码
- 1.2.2 编译源码
- 1.3 工具介绍
- 1.3.1 Source Insight介绍
- 1.3.2 Busybox的使用
- 1.4 本章小结
- 第2章 深入理解JNI
- 2.1 JNI概述
- 2.2 学习JNI的实例:MediaScanner
- 2.3 Java层的MediaScanner分析
- 2.3.1 加载JNI库
- 2.3.2 Java的native函数和总结
- 2.4 JNI层MediaScanner的分析
- 2.4.1 注册JNI函数
- 2.4.2 数据类型转换
- 2.4.3 JNIEnv介绍
- 2.4.4 通过JNIEnv操作jobject
- 2.4.5 jstring介绍
- 2.4.6 JNI类型签名介绍
- 2.4.7 垃圾回收
- 2.4.8 JNI中的异常处理
- 2.5 本章小结
- 第3章 深入理解init
- 3.1 概述
- 3.2 init分析
- 3.2.1 解析配置文件
- 3.2.2 解析service
- 3.2.3 init控制service
- 3.2.4 属性服务
- 3.3 本章小结
- 第4章 深入理解zygote
- 4.1 概述
- 4.2 zygote分析
- 4.2.1 AppRuntime分析
- 4.2.2 Welcome to Java World
- 4.2.3 关于zygote的总结
- 4.3 SystemServer分析
- 4.3.1 SystemServer的诞生
- 4.3.2 SystemServer的重要使命
- 4.3.3 关于 SystemServer的总结
- 4.4 zygote的分裂
- 4.4.1 ActivityManagerService发送请求
- 4.4.2 有求必应之响应请求
- 4.4.3 关于zygote分裂的总结
- 4.5 拓展思考
- 4.5.1 虚拟机heapsize的限制
- 4.5.2 开机速度优化
- 4.5.3 Watchdog分析
- 4.6 本章小结
- 第5章 深入理解常见类
- 5.1 概述
- 5.2 以“三板斧”揭秘RefBase、sp和wp
- 5.2.1 第一板斧--初识影子对象
- 5.2.2 第二板斧--由弱生强
- 5.2.3 第三板斧--破解生死魔咒
- 5.2.4 轻量级的引用计数控制类LightRefBase
- 5.2.5 题外话-三板斧的来历
- 5.3 Thread类及常用同步类分析
- 5.3.1 一个变量引发的思考
- 5.3.2 常用同步类
- 5.4 Looper和Handler类分析
- 5.4.1 Looper类分析
- 5.4.2 Handler分析
- 5.4.3 Looper和Handler的同步关系
- 5.4.4 HandlerThread介绍
- 5.5 本章小结
- 第6章 深入理解Binder
- 6.1 概述
- 6.2 庖丁解MediaServer
- 6.2.1 MediaServer的入口函数
- 6.2.2 独一无二的ProcessState
- 6.2.3 时空穿越魔术-defaultServiceManager
- 6.2.4 注册MediaPlayerService
- 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析
- 6.2.6 你彻底明白了吗
- 6.3 服务总管ServiceManager
- 6.3.1 ServiceManager的原理
- 6.3.2 服务的注册
- 6.3.3 ServiceManager存在的意义
- 6.4 MediaPlayerService和它的Client
- 6.4.1 查询ServiceManager
- 6.4.2 子承父业
- 6.5 拓展思考
- 6.5.1 Binder和线程的关系
- 6.5.2 有人情味的讣告
- 6.5.3 匿名Service
- 6.6 学以致用
- 6.6.1 纯Native的Service
- 6.6.2 扶得起的“阿斗”(aidl)
- 6.7 本章小结
- 第7章 深入理解Audio系统
- 7.1 概述
- 7.2 AudioTrack的破解
- 7.2.1 用例介绍
- 7.2.2 AudioTrack(Java空间)分析
- 7.2.3 AudioTrack(Native空间)分析
- 7.2.4 关于AudioTrack的总结
- 7.3 AudioFlinger的破解
- 7.3.1 AudioFlinger的诞生
- 7.3.2 通过流程分析AudioFlinger
- 7.3.3 audio_track_cblk_t分析
- 7.3.4 关于AudioFlinger的总结
- 7.4 AudioPolicyService的破解
- 7.4.1 AudioPolicyService的创建
- 7.4.2 重回AudioTrack
- 7.4.3 声音路由切换实例分析
- 7.4.4 关于AudioPolicy的总结
- 7.5 拓展思考
- 7.5.1 DuplicatingThread破解
- 7.5.2 题外话
- 7.6 本章小结
- 第8章 深入理解Surface系统
- 8.1 概述
- 8.2 一个Activity的显示
- 8.2.1 Activity的创建
- 8.2.2 Activity的UI绘制
- 8.2.3 关于Activity的总结
- 8.3 初识Surface
- 8.3.1 和Surface有关的流程总结
- 8.3.2 Surface之乾坤大挪移
- 8.3.3 乾坤大挪移的JNI层分析
- 8.3.4 Surface和画图
- 8.3.5 初识Surface小结
- 8.4 深入分析Surface
- 8.4.1 与Surface相关的基础知识介绍
- 8.4.2 SurfaceComposerClient分析
- 8.4.3 SurfaceControl分析
- 8.4.4 writeToParcel和Surface对象的创建
- 8.4.5 lockCanvas和unlockCanvasAndPost分析
- 8.4.6 GraphicBuffer介绍
- 8.4.7 深入分析Surface的总结
- 8.5 SurfaceFlinger分析
- 8.5.1 SurfaceFlinger的诞生
- 8.5.2 SF工作线程分析
- 8.5.3 Transaction分析
- 8.5.4 关于SurfaceFlinger的总结
- 8.6 拓展思考
- 8.6.1 Surface系统的CB对象分析
- 8.6.2 ViewRoot的你问我答
- 8.6.3 LayerBuffer分析
- 8.7 本章小结
- 第9章 深入理解Vold和Rild
- 9.1 概述
- 9.2 Vold的原理与机制分析
- 9.2.1 Netlink和Uevent介绍
- 9.2.2 初识Vold
- 9.2.3 NetlinkManager模块分析
- 9.2.4 VolumeManager模块分析
- 9.2.5 CommandListener模块分析
- 9.2.6 Vold实例分析
- 9.2.7 关于Vold的总结
- 9.3 Rild的原理与机制分析
- 9.3.1 初识Rild
- 9.3.2 RIL_startEventLoop分析
- 9.3.3 RIL_Init分析
- 9.3.4 RIL_register分析
- 9.3.5 关于Rild main函数的总结
- 9.3.6 Rild实例分析
- 9.3.7 关于Rild的总结
- 9.4 拓展思考
- 9.4.1 嵌入式系统的存储知识介绍
- 9.4.2 Rild和Phone的改进探讨
- 9.5 本章小结
- 第10章 深入理解MediaScanner
- 10.1 概述
- 10.2 android.process.media分析
- 10.2.1 MSR模块分析
- 10.2.2 MSS模块分析
- 10.2.3 android.process.media媒体扫描工作的流程总结
- 10.3 MediaScanner分析
- 10.3.1 Java层分析
- 10.3.2 JNI层分析
- 10.3.3 PVMediaScanner分析
- 10.3.4 关于MediaScanner的总结
- 10.4 拓展思考
- 10.4.1 MediaScannerConnection介绍
- 10.4.2 我问你答
- 10.5 本章小结