前文讲述的内容都集中在Java层,下面要按照流程顺序分析JNI层的内容。
1. Surface的无参构造分析
在JNI层,第一个被调用的是Surface的无参构造函数,其代码如下所示:
**Surface.java**
~~~
public Surface() {
......
//CompatibleCanvas从Canvas类派生
mCanvas = new CompatibleCanvas();
}
~~~
Canvas是什么?根据SDK文档的介绍可知,画图需要“四大金刚”相互合作,这四大金刚是:
- Bitmap:用于存储像素,也就是画布。可把它当做一块数据存储区域。
- Canvas:用于记载画图的动作,比如画一个圆,画一个矩形等。Canvas类提供了这些基本的绘图函数。
- Drawing primitive:绘图基元,例如矩形、圆、弧线、文本、图片等。
- Paint:它用来描述绘画时使用的颜色、风格(如实线、虚线等)等。
在一般情况下,Canvas会封装一块Bitmap,而作图就是基于这块Bitmap的。前面说的画布,其实指的就是Canvas中的这块Bitmap。
这些知识稍了解即可,不必去深究。Surface的无参构造函数没有什么有价值的内容,接着看下面的内容。
2. SurfaceSession的构造
现在要分析的是SurfaceSession,其构造函数如下所示:
**SurfaceSession.java**
~~~
public SurfaceSession() {
init();//这是一个native函数
}
~~~
init是一个native函数。去看看它的JNI实现,它在android_view_Surface.cpp中,代码如下所示:
**android_view_Surface.cpp**
~~~
static void SurfaceSession_init(JNIEnv* env,jobject clazz)
{
//创建一个SurfaceComposerClient对象
sp<SurfaceComposerClient> client = new SurfaceComposerClient;
client->incStrong(clazz);
//在Java对象中保存这个client对象的指针,类型为SurfaceComposerClient
env->SetIntField(clazz, sso.client, (int)client.get());
}
~~~
这里先不讨论SurfaceComposerClient的内容,拟继续把乾坤大挪移的流程走完。
3. Surface的有参构造
下一个调用的是Surface的有参构造,其参数中有一个SurfaceSession。先看Java层的代码,如下所示:
**Surface.java**
~~~
publicSurface(SurfaceSession s,//传入一个SurfaceSession对象
int pid, String name, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
......
mCanvas = new CompatibleCanvas();
//又一个native函数,注意传递的参数:display以后再说,w,h代表绘图区域的宽高值
init(s,pid,name,display,w,h,format,flags);
mName = name;
}
~~~
Surface的native init函数的JNI实现,也在android_view_Surface.cpp中,一起来看:
**android_view_Surface.cpp**
~~~
static void Surface_init(
JNIEnv*env, jobject clazz,
jobject session,
jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags)
{
//从SurfaceSession对象中取出之前创建的那个SurfaceComposerClient对象
SurfaceComposerClient* client =
(SurfaceComposerClient*)env->GetIntField(session, sso.client);
sp<SurfaceControl> surface;//注意它的类型是SurfaceControl
if (jname == NULL) {
/*
调用SurfaceComposerClient的createSurface函数,返回的surface是一个
SurfaceControl类型。
*/
surface = client->createSurface(pid, dpy, w, h, format, flags);
} else{
......
}
//把这个surfaceControl对象设置到Java层的Surface对象中,对这个函数就不再分析了
setSurfaceControl(env, clazz, surface);
}
~~~
4. copyFrom的分析
现在要分析的就是copyFrom了。它就是一个native函数。看它的JNI层代码:
**android_view_Surface.cpp**
~~~
static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other)
{
//根据JNI函数的规则,clazz是copyFrom的调用对象,而other是copyFrom的参数。
//目标对象此时还没有设置SurfaceControl,而源对象在前面已经创建了SurfaceControl
constsp<SurfaceControl>& surface = getSurfaceControl(env, clazz);
constsp<SurfaceControl>& rhs = getSurfaceControl(env, other);
if (!SurfaceControl::isSameSurface(surface, rhs)) {
//把源SurfaceControl对象设置到目标Surface中。
setSurfaceControl(env, clazz, rhs);
}
}
~~~
这一步还是比较简单的,下面看第五步writeToParcel函数的调用。
5. writeToParcel的分析
多亏了必杀技aidl工具的帮忙,才挖出这个隐藏的writeToParcel函数调用,下面就来看看它,代码如下所示:
**android_view_Surface.cpp**
~~~
static void Surface_writeToParcel(JNIEnv* env,jobject clazz,
jobject argParcel, jint flags)
{
Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel);
//clazz就是Surface对象,从这个Surface对象中取出保存的SurfaceControl对象
const sp<SurfaceControl>&control(getSurfaceControl(env, clazz));
/*
把SurfaceControl中的信息写到Parcel包中,然后利用Binder通信传递到对端,
对端通过readFromParcel来处理Parcel包。
*/
SurfaceControl::writeSurfaceToParcel(control, parcel);
if (flags & PARCELABLE_WRITE_RETURN_VALUE) {
//还记得PARCELABLE_WRITE_RETURN_VALUE吗?flags的值就等于它
//所以本地Surface对象的SurfaceControl值被置空了
setSurfaceControl(env, clazz, 0);
}
}
~~~
6. readFromParcel的分析
再看作为客户端的ViewRoot所调用的readFromParcel函数。它也是一个native函数,JNI层的代码如下所示:
**android_view_Surface.cpp**
~~~
static void Surface_readFromParcel(JNIEnv* env, jobject clazz, jobject argParcel)
{
Parcel* parcel = (Parcel*)env->GetIntField( argParcel,no.native_parcel);
//注意下面定义的变量类型是Surface,而不是SurfaceControl
const sp<Surface>&control(getSurface(env, clazz));
//根据服务端传递的Parcel包来构造一个新的surface。
sp<Surface> rhs = new Surface(*parcel);
if (!Surface::isSameSurface(control, rhs)) {
//把这个新surface赋给ViewRoot中的mSurface对象。
setSurface(env,clazz, rhs);
}
}
~~~
7. Surface乾坤大挪移的小结
可能有人会问,乾坤大挪移怎么这么复杂?这期间出现了多少对象?来总结一下,在此期间一共有三个关键对象(注意我们这里只考虑JNI层的Native对象),它们分别是:
- SurfaceComposerClient。
- SurfaceControl。
- Surface,这个Surface对象属于Native层,和Java层的Surface相对应。
其中转移到ViewRoot成员变量mSurface中的,就是最后这个Surface对象了。这一路走来,真是异常坎坷。来回顾并概括总结一下这段历程。至于它的作用应该是很清楚了。以后要破解SurfaceFlinger,靠的就是这个精简的流程。
- 创建一个SurfaceComposerClient。
- 调用SurfaceComposerClient的createSurface得到一个SurfaceControl对象。
- 调用SurfaceControl的writeToParcel把一些信息写到Parcel包中。
- 根据Parcel包的信息构造一个Surface对象。这个Surface对象保存到Java层的mSurface对象中。这样,大挪移的结果是ViewRoot得到一个Native的Surface对象。
>[info] **注意**:精简流程后,寥寥数语就可把过程说清楚。以后我们在研究代码时,也可以采取这种方式。
这个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 本章小结