天天看點

Android5.0 Recovery源代碼分析與定制---recovery UI相關(二)

在上一篇文章中,我們大緻的介紹了recovery的啟動流程,那麼,recovery更新或者做雙清的時候,那些圖形動畫又是如何實作的呢?我們來看看代碼:

     以下這段代碼位于recovery/screen_ui.cpp

這段代碼都做了哪些事情呢?這些recovery初始化圖形顯示最開始的部分,

(1)調用了miniui中的gr_init初始化顯示圖形相關的步驟,因為recovery是基于framebuffer機制顯示的。

(2)調用gr_font_size設定字型顯示的大小,然後計算文本顯示行列。

(3)接下來就是裝載圖檔了,會調用到LoadBitmapArray和LoadBitmap這兩個函數。其中,我們會看到這些函數裡圖檔的名稱:

"icon_installing"、"icon_error"、"progress_empty"、"progress_fill"、

        "stage_empty"、"stage_fill"、"installing_text"、"erasing_text"、

        "no_command_text"、"error_text"

将上面的字元串與下面的圖檔一一對應:

Android5.0 Recovery源代碼分析與定制---recovery UI相關(二)

那麼這些分别是怎麼顯示的?其中erasing_text是用來顯示做清除的時候顯示的文字,放大後如下:

Android5.0 Recovery源代碼分析與定制---recovery UI相關(二)

這上面有許許多多的語言版本,我們可以根據需要來選擇,這些主要要看接下來初始化文字的代碼邏輯。

其餘的圖檔中,字尾帶text的,也和這些是類似的,有出現錯誤顯示的字型error_text,更新系統顯示的字型installing_text,沒有指令的時候顯示的字型no_command_text。

除了文字顯示,我們最關心的就是icon_installing這張圖檔了,在做系統更新的時候,這個機器人會轉動。這不是動畫嗎?怎麼隻有一張圖檔呢?我們找到Android官方網站看看是為什麼?

原因如下:

Recovery UI images

Android 5.x

The recovery user interface consists images. Ideally, users never interact with the UI: During a normal update, 

the phone boots into recovery, fills the installation progress bar, and boots back into the new system without 

input from the user. In the event of a system update problem, the only user action that can be taken is to 

call customer care.An image-only interface obviates the need for localization. 

However, as of Android 5.x the update can display a string of text (e.g. "Installing system update...") 

along with the image. For details, see Localized recovery text.

Android5.0 Recovery源代碼分析與定制---recovery UI相關(二)

efault images are available in different densities and are located inbootable/recovery/res$DENSITY/images 

(e.g., bootable/recovery/res-hdpi/images). To use a static image during installation, 

you need only provide the icon_installing.png image and set the number of frames in the animation to 0 

(the error icon is not animated; it is always a static image).

// 以上文檔意思就是說,Android5.x以上的版本,機器人的動畫是PNG圖檔和幀動畫組成的,

//我們可以使用recovery目錄下的interlace-frames.py這個python腳本來進行合成,

//具體的合成方法需要使用recovery代碼中的一個python合成工具。

//我就可以把android原生态的動畫給換了,因為這個機器人實在是醜。

源碼如下:

這也就是為什麼,調用這張圖檔需要用到LoadBitmapArray這個函數的原因。

調完這個函數後會調用resources.cpp中的res_create_multi_display_surface函數用于顯示,源碼如下:

其餘的和text無關圖檔,會用到LoadBitmap這個函數:

同樣調用到以下函數:

關于圖檔我們大概都知道怎麼來顯示的了,是以,現在我們可以替換Android原生态中的圖檔,換成我們自己的圖檔,

當然,也不是什麼圖都可以的,在recovery中,所有的png圖檔必須是RGB且不帶且不能帶alhpa通道資訊。

關于這一點,我們可以看open_png這個函數:

在代碼中,我們可以看到如下:

以下參考一位網友給出的答案。

這個函數将圖檔檔案的資料讀取到記憶體,我在其中輸出了一些調試資訊,輸出圖檔的 color_type, channels 等資訊。

檢視LOG發現,android原生的圖檔 channels == 3,channels 即色彩通道個數,等于 3 的話,意味着隻有 R,G,B 三個通道的資訊,

沒有 ALPHA 通道資訊!這段代碼的邏輯是如果channels 不等于3, 則按channels = 1 來處理,即灰階圖。

美工給的圖檔是帶 alpha通道資訊的,即channels = 4,被當成灰階圖像來處理了,怪不得顯示的效果是灰階圖像。

我一直以為 png 圖像就隻有一種格式,都是帶有 alpha通道的。。。

使用圖像處理工具(photoshop 或者 gimp),将美工給的圖檔去掉 alpha 通道資訊,再替換recovery 的圖檔,編譯,替換recovery.img ,

reboot -r 。圖檔終于正常顯示啦。

在下一節裡,我們将繼續分析UI顯示....