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:
:-: 
圖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:
:-: 
圖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來表示:
:-: 
圖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 本章小結