多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Recovery模式本地化文本顯示

Recovery模式本地化文本顯示

來源:程序員人生   發布時間:2015-04-29 08:00:49 閱讀次數:3364次

寫在前面:

本篇博文所討論的內容主要是與大家1起討論Recovery模式本地化顯示文本的原理,和如何使用谷歌提供的recovery_l10n工具實現定制本地化顯示的文本。

導讀:

首先我們來討論Recovery模式下本地化文本的顯示是如何實現的。

先看兩張圖,相信很多人都很熟習,第1張是我們恢復出廠設置操作,關機重啟進入recovery模式以后所看到的界面,第2張是通過按鍵進入recovery模式,帶有選項菜單的主界面。1般來講普通用戶正常的操作是不會看到第2個界面的,而在第1張圖片中我們看到,在綠色小機器人下面有1行字符,這行字符就是本文的關鍵。

 

1:恢復出廠設置-擦除數據

 

2recovery模式主界面-選項菜單

其實上面這行文本內容其實不是以字符的情勢顯示的,而是用圖片代替,以下圖:

 

3:本地化文本圖片合成

補充1下,就是說當Recovery模式下需要顯示這些文本信息的時候,會根據進入recovery模式前的系統語言來從上面這張圖片中截取對應語言的文本信息,也就是說這個信息其實不是直接用C語言打印輸出到屏幕上的。

 

Recovery模式下是不支持系統語言庫的,但是recovery中文本信息本地化又是與主系統當前語言環境保持同步的,那末,在recovery模式是如何與主系統進行交互的呢?

主系統與recovery通過command文件中特定的參數進行交互的。

1、Framework

        首先來看framework/base/core/java/android/os/RecoverySystem.java中的代碼片斷:

/** RECOVERY_DIR是用來與recovery系統交互的目錄,也就是說主系統與recovery系統是通過文件進行交互的. 詳情可了解 bootable/recovery/recovery.c. */ private static File RECOVERY_DIR = new File("/cache/recovery"); private static File COMMAND_FILE = new File(RECOVERY_DIR, "command"); /* 安裝指定的更新包并進行重啟*/ public static void installPackage(Context context, File packageFile) throws IOException { String filename = packageFile.getCanonicalPath()//得到更新包路徑 ...... final String filenameArg = "--update_package=" + filename;//將更新包路徑作為參數傳遞寫入Command文件 final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化參數 bootCommand(context, filenameArg, localeArg);//重啟,并將參數寫入command文件 } /*擦除data和cache分區的數據并重啟*/ public static void rebootWipeUserData(Context context, boolean shutdown, String reason) throws IOException { ...... String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after"; } String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化參數 bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } /*擦除cache分區的數據并重啟*/ public static void rebootWipeCache(Context context, String reason) throws IOException { ...... final String localeArg = "--locale=" + Locale.getDefault().toString();//本地化參數 bootCommand(context, "--wipe_cache", reasonArg, localeArg); } /*重啟進入recovery模式,并根據指定的參數指定相對應的操作,如安裝更新,擦除用戶數據等*/ private static void bootCommand(Context context, String... args) throws IOException { RECOVERY_DIR.mkdirs(); // In case we need it COMMAND_FILE.delete(); // In case it's not writable LOG_FILE.delete(); /*向command文件中寫入指定的參數*/ FileWriter command = new FileWriter(COMMAND_FILE); try { for (String arg : args) { if (!TextUtils.isEmpty(arg)) { command.write(arg); command.write(" "); } } } finally { command.close(); } // Having written the command file, go ahead and reboot PowerManager pm=(PowerManager)context.getSystemService(Context.POWER_SERVICE); pm.reboot(PowerManager.REBOOT_RECOVERY); throw new IOException("Reboot failed (no permissions?)"); }

從上面代碼告知我們,主系統是通過COMMAND_FILE文件的情勢與recovery進行交互,根據不同的命令行參數履行不同的操作,如系統升級、恢復出廠設置等。

2、BCB (bootloader control block)bootloader_message

    BCB主要用來加載和啟動系統,并且通過讀取flashMISC分區中主系統和recovery的信息,并做出相應處理。BCB既是BootloaderRecovery的通訊接口,也是Bootloader與主系統的接口,為何呢?我們來了解下BCB的結構體:

struct bootloader_message {

    char command[32];

    char status[32];

    char recovery[1024];

};

從上面1部份我們了解到當系統進行恢復出廠設置操作時會將主系統當前的語言環境作為參數寫入/bootable/recovery/command中,而上面結構體中的command區域就是主系統與recovery交互式所操作的區域,當主系統想要進入recovery模式時,會修改MISC分區中command區域并重啟,而Bootloader會根據command區域中的信息來決定是進入主系統還是recovery系統。

    /system/core/init/signal_handler.c里的wait_for_one_process函數中有以下代碼:

 

    android_reboot(ANDROID_RB_RESTART2, 0, "recovery")->

 

        __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,

 

        LINUX_REBOOT_CMD_RESTART2, recovery);

 

因此BCB就成了主系統與recovery進行交互的橋梁。

3、Recovery模式

BCB加載recovery.img來啟動recovery模式時,會在recoveryinitrckernel啟動完成后啟動第1個recovery服務,也就是recovery.cpp,位于/bootable/recovery/目錄下。

recovery.c中會首先履行get_args函數(如,get_args(&argc, &argv);),用來獲得命令行參數,也就是讀取/cache/recovery/command中的命令行參數。get_args不但會獲得到命令行參數也會將獲得到的參數寫入到MISC分區中,這樣1旦在履行升級或恢復出廠設置進程中失敗,重啟以后照舊會進入recovery模式重新履行之前失敗的動作。

Recovery模式是支持command文件中特定參數的,如OPTIONS[]中的定義:

static const struct option OPTIONS[] = {

  { "send_intent", required_argument, NULL, 's' }//intent文件中寫入數據

  { "update_package", required_argument, NULL, 'u' },//驗證ota package路徑下更新包文件

  { "wipe_data", no_argument, NULL, 'w' },//擦除data分區

  { "wipe_cache", no_argument, NULL, 'c' },//擦除cache分區

  { "show_text", no_argument, NULL, 't' },//顯示主菜單

  { "just_exit", no_argument, NULL, 'x' },//退出并重啟

  { "locale", required_argument, NULL, 'l' },//本地化

  { NULL, 0, NULL, 0 },

};

    當我們恢復出廠設置重啟進入recovery模式時會首先履行recovery.cppmain函數,recovery系統會將/cache/recovery/command中的內容作為命令行參數傳遞給main函數:

/bootable/recovery/recovery.cpp

    int arg;

    while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != ⑴) {

        switch (arg) {

        case 'p': previous_runs = atoi(optarg); break;

        case 's': send_intent = optarg; break;

        case 'u': update_package = optarg; break;

        case 'w': wipe_data = wipe_cache = 1; break;

        case 'c': wipe_cache = 1; break;

        case 't': show_text = 1; break;

        case 'x': just_exit = true; break;

        case 'l': locale = optarg; break;

        case '?':

            LOGE("Invalid command argument ");

            continue;

        }

}

if (locale == NULL) {

    load_locale_from_cache();

}

printf("locale is [%s] ", locale);

Device* device = make_device();

ui = device->GetUI();

ui->Init();

ui->SetLocale(locale);

ui->SetBackground(RecoveryUI::NONE);

if (show_text) ui->ShowText(true);

上面getopt被用來解析命令行選項參數,而getopt_long支持長選項的命令行解析,第3個參數指的就是命令行選項參數所組成的字符串,如果單個字符后面跟了1個冒號則表示該選項后面必須跟1個參數,而參數的指針會復制給optarg。在上面這段代碼中,參數“l”指的就是本地化。Recovery系統會根據這個參數(如--local=en)來決定第1張圖中的文字對應的時第3張圖的哪1部份的。那末我們恢復出廠設置操作的時,command中所對應的參數是甚么模樣的呢,看下面:

--wipe_data

--locale=en

這樣的話,也就解釋了case 'l': locale = optarg; break;中變量為什么從optarg中取值了。

然后recovery會通過下面1系列的函數調用來實現對預制png圖片中對應的文本信息進行截取,以下:

bootable/recovery/screen_ui.cpp)ScreenRecoveryUI::Init()-->ScreenRecoveryUI::LoadLocalizedBitmap()-->(bootable/recovery/minui/resources.c)res_create_localized_surface();

int res_create_localized_surface(const char* name, gr_surface* pSurface) {

    char resPath[256];

    GGLSurface* surface = NULL;

    int result = 0;

    unsigned char header[8];

    png_structp png_ptr = NULL;

    png_infop info_ptr = NULL;

    *pSurface = NULL;

    snprintf(resPath, sizeof(resPath)⑴, "/res/images/%s.png", name);

    resPath[sizeof(resPath)⑴] = '

主站蜘蛛池模板: 国产三级在线播放 | 亚洲成a人不卡在线观看 | 国产一级淫片a | 毛片毛片毛片毛片出来毛片 | 亚洲天堂伦理 | 真实国产精品视频国产网 | xxxxwww日本 | 亚洲天堂影院在线观看 | 午夜在线影院 | 亚洲色图另类小说 | 免费看羞羞动漫视频网站 | 片在线观看免费观看视频 | 亚洲视频在线观看地址 | 中文乱码一本到无线202 | 日本亚州在线播放精品 | 国产一区二区三区四区五区六区 | 欧美一级成人一区二区三区 | 亚洲精品久久99久久一区 | 日韩精品在线一区 | 中文字幕视频在线观看 | 性短视频在线观看免费不卡流畅 | 亚洲黄色视屏 | 久久免费视频观看 | 亚洲区欧美中文字幕久久 | 最近高清中文在线观看国语字幕7 | 国产淫视频 | xxx日本护士www | 亚洲一级在线观看 | 国产精品久久在线观看 | 国产精品v | 国产福利观看 | 美国一级毛片片aa久久综合 | 久久综合九色综合欧洲色 | 波多野结衣久久精品 | 美女又黄又免费 | 日韩欧美亚 | 无码精品一区二区三区免费视频 | 欧美亚洲国产成人不卡 | 性欧美另类 | 日韩欧美一及在线播放 | 久久91综合国产91久久精品 |