Android系統的開機畫面顯示過程分析(8)

??? ?3. 第三個開機畫面的顯示過程
?? ? ? ?第三個開機畫面是由應用程序bootanimation來負責顯示的。應用程序bootanimation在啟動腳本init.rc中被配置成了一個服務,如下所示:
  1. service?bootanim?/system/bin/bootanimation??
  2. ????user?graphics??
  3. ????group?graphics??
  4. ????disabled??
  5. ????oneshot??
?? ? ? 應用程序bootanimation的用戶和用戶組名稱分別被設置為graphics。注意,?用來啟動應用程序bootanimation的服務是disable的,即init進程在啟動的時候,不會主動將應用程序bootanimation啟動起來。當SurfaceFlinger服務啟動的時候,它會通過修改系統屬性ctl.start的值來通知init進程啟動應用程序bootanimation,以便可以顯示第三個開機畫面,而當System進程將系統中的關鍵服務都啟動起來之后,ActivityManagerService服務就會通知SurfaceFlinger服務來修改系統屬性ctl.stop的值,以便可以通知init進程停止執行應用程序bootanimation,即停止顯示第三個開機畫面。接下來我們就分別分析第三個開機畫面的顯示過程和停止過程。
?? ? ?從前面Android系統進程Zygote啟動過程的源代碼分析一文可以知道,Zygote進程在啟動的過程中,會將System進程啟動起來,而從前面Android應用程序安裝過程源代碼分析一文又可以知道,System進程在啟動的過程(Step 3)中,會調用SurfaceFlinger類的靜態成員函數instantiate來啟動SurfaceFlinger服務。Sytem進程在啟動SurfaceFlinger服務的過程中,首先會創建一個SurfaceFlinger實例,然后再將這個實例注冊到Service Manager中去。在注冊的過程,前面創建的SurfaceFlinger實例會被一個sp指針引用。從前面Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析一文可以知道,當一個對象第一次被智能指針引用的時候,這個對象的成員函數onFirstRef就會被調用。由于SurfaceFlinger重寫了父類RefBase的成員函數onFirstRef,因此,在注冊SurfaceFlinger服務的過程中,將會調用SurfaceFlinger類的成員函數onFirstRef。在調用的過程,就會創建一個線程來啟動第三個開機畫面。
?? ? ??SurfaceFlinger類實現在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 中,它的成員函數onFirstRef的實現如下所示:
  1. void?SurfaceFlinger::onFirstRef()??
  2. {??
  3. ????run("SurfaceFlinger",?PRIORITY_URGENT_DISPLAY);??
  4. ??
  5. ????//?Wait?for?the?main?thread?to?be?done?with?its?initialization??
  6. ????mReadyToRunBarrier.wait();??
  7. }??
?? ? ? ?SurfaceFlinger類繼承了Thread類,當它的成員函數run被調用的時候,系統就會創建一個新的線程。這個線程在第一次運行之前,會調用SurfaceFlinger類的成員函數readyToRun來通知SurfaceFlinger,它準備就緒了。當這個線程準備就緒之后,它就會循環執行SurfaceFlinger類的成員函數threadLoop,直到這個成員函數的返回值等于false為止。
?? ? ? ?注意,SurfaceFlinger類的成員函數onFirstRef是在System進程的主線程中調用的,它需要等待前面創建的線程準備就緒之后,再繼續往前執行,這個通過調用SurfaceFlinger類的成員變量mReadytoRunBarrier所描述的一個Barrier對象的成員函數wait來實現的。每一個Barrier對象內問都封裝了一個條件變量(Condition Variable),而條件變量是用來同步線程的。
?? ? ? ?接下來,我們繼續分析SurfaceFlinger類的成員函數readyToRun的實現,如下所示:
  1. status_t?SurfaceFlinger::readyToRun()??
  2. {??
  3. ????LOGI(???"SurfaceFlinger's?main?thread?ready?to?run.?"??
  4. ????????????"Initializing?graphics?H/W...");??
  5. ??????
  6. ????......??
  7. ??
  8. ????mReadyToRunBarrier.open();??
  9. ??
  10. ????/*?
  11. ?????*??We're?now?ready?to?accept?clients...?
  12. ?????*/??
  13. ??
  14. ????//?start?boot?animation??
  15. ????property_set("ctl.start",?"bootanim");??
  16. ??
  17. ????return?NO_ERROR;??
  18. }??

?? ? ? 前面創建的線程用作SurfaceFlinger的主線程。這個線程在啟動的時候,會對設備主屏幕以及OpenGL庫進行初始化。初始化完成之后,接著就會調用SurfaceFlinger類的成員變量mReadyToRunBarrier所描述的一個Barrier對象的成員函數open來喚醒System進程的主線程,以便它可以繼續往前執行。最后,SurfaceFlinger類的成員函數readyToRun的成員函數會調用函數property_set來將系統屬性“ctl.start”的值設置為“bootanim”,表示要將應用程序bootanimation啟動起來,以便可以顯示第三個開機畫面。
?? ? ? 前面在介紹第二個開機畫面的時候提到,當系統屬性發生改變時,init進程就會接收到一個系統屬性變化通知,這個通知最終是由在init進程中的函數handle_property_set_fd來處理的。
?? ? ? 函數handle_property_set_fd實現在文件system/core/init/property_service.c中,如下所示:
  1. void?handle_property_set_fd()??
  2. {??
  3. ????prop_msg?msg;??
  4. ????int?s;??
  5. ????int?r;??
  6. ????int?res;??
  7. ????struct?ucred?cr;??
  8. ????struct?sockaddr_un?addr;??
  9. ????socklen_t?addr_size?=?sizeof(addr);??
  10. ????socklen_t?cr_size?=?sizeof(cr);??
  11. ??
  12. ????if?((s?=?accept(property_set_fd,?(struct?sockaddr?*)?&addr,?&addr_size))?<?0)?{??
  13. ????????return;??
  14. ????}??
  15. ??
  16. ????/*?Check?socket?options?here?*/??
  17. ????if?(getsockopt(s,?SOL_SOCKET,?SO_PEERCRED,?&cr,?&cr_size)?<?0)?{??
  18. ????????close(s);??
  19. ????????ERROR("Unable?to?recieve?socket?options\n");??
  20. ????????return;??
  21. ????}??
  22. ??
  23. ????r?=?recv(s,?&msg,?sizeof(msg),?0);??
  24. ????close(s);??
  25. ????if(r?!=?sizeof(prop_msg))?{??
  26. ????????ERROR("sys_prop:?mis-match?msg?size?recieved:?%d?expected:?%d\n",??
  27. ??????????????r,?sizeof(prop_msg));??
  28. ????????return;??
  29. ????}??
  30. ??
  31. ????switch(msg.cmd)?{??
  32. ????case?PROP_MSG_SETPROP:??
  33. ????????msg.name[PROP_NAME_MAX-1]?=?0;??
  34. ????????msg.value[PROP_VALUE_MAX-1]?=?0;??
  35. ??
  36. ????????if(memcmp(msg.name,"ctl.",4)?==?0)?{??
  37. ????????????if?(check_control_perms(msg.value,?cr.uid,?cr.gid))?{??
  38. ????????????????handle_control_message((char*)?msg.name?+?4,?(char*)?msg.value);??
  39. ????????????}?else?{??
  40. ????????????????ERROR("sys_prop:?Unable?to?%s?service?ctl?[%s]?uid:?%d?pid:%d\n",??
  41. ????????????????????????msg.name?+?4,?msg.value,?cr.uid,?cr.pid);??
  42. ????????????}??
  43. ????????}?else?{??
  44. ????????????if?(check_perms(msg.name,?cr.uid,?cr.gid))?{??
  45. ????????????????property_set((char*)?msg.name,?(char*)?msg.value);??
  46. ????????????}?else?{??
  47. ????????????????ERROR("sys_prop:?permission?denied?uid:%d??name:%s\n",??
  48. ??????????????????????cr.uid,?msg.name);??
  49. ????????????}??
  50. ????????}??
  51. ????????break;??
  52. ??
  53. ????default:??
  54. ????????break;??
  55. ????}??
  56. }??

?? ? ? ?init進程是通過一個socket來接收系統屬性變化事件的。每一個系統屬性變化事件的內容都是通過一個prop_msg對象來描述的。在prop_msg對象對,成員變量name用來描述發生變化的系統屬性的名稱,而成員變量value用來描述發生變化的系統屬性的值。系統屬性分為兩種類型,一種是普通類型的系統屬性,另一種是控制類型的系統屬性(屬性名稱以“ctl.”開頭)。控制類型的系統屬性在發生變化時,會觸發init進程執行一個命令,而普通類型的系統屬性就不具有這個特性。注意,改變系統屬性是需要權限,因此,函數handle_property_set_fd在處理一個系統屬性變化事件之前,首先會檢查修改系統屬性的進程是否具有相應的權限,這是通過調用函數check_control_perms或者check_perms來實現的。
?? ? ? ?從前面的調用過程可以知道,當前發生變化的系統屬性的名稱為“ctl.start”,它的值被設置為“bootanim”。由于這是一個控制類型的系統屬性,因此,在通過了權限檢查之后,另外一個函數handle_control_message就會被調用,以便可以執行一個名稱為“bootanim”的命令。




本文轉自 Luoshengyang 51CTO博客,原文鏈接:http://blog.51cto.com/shyluo/967040,如需轉載請自行聯系原作者

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/279830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/279830.shtml
英文地址,請注明出處:http://en.pswp.cn/news/279830.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

chrome連接已重置_如何重置(或調整)Chrome的下載設置

chrome連接已重置By default, Chrome saves all downloaded files to the same location—a dedicated “Downloads” folder. The thing is, this isn’t always practical for all types of download files. The good news is you can easily tweak this setting. 默認情況下…

.Net 7 團隊把國內的龍芯確實當做一等公民和棄用的項目

楔子&#xff1a;國內龍芯據說是用的自己的指令集&#xff0c;在研究ILC的時候&#xff0c;發現了龍芯在微軟那邊確實是一等公民的存在。同X64,ARM,X86一同并列交叉編譯和二進制提取。龍芯官網龍芯平臺.NET&#xff0c;是龍芯公司基于開源社區.NET獨立研發適配的龍芯版本&#…

戴爾押寶iSCSI,由低到高組合成型

戴爾&#xff08;Dell&#xff09;是較早接受SAS技術的主流存儲廠商之一&#xff0c;2006年已推出采用SAS硬盤驅動器的SAS直連存儲&#xff08;DAS&#xff09;系統PowerVault MD3000。一年之后&#xff0c;主機連接改用iSCSI的PowerVault MD3000i問世。2008年1月&#xff0c;E…

仿Gin搭建自己的web框架(七)

本篇介紹HTTP Basic Auth的實現以及Recovery機制。 HTTP Basic Auth Basic Auth是一種開放平臺認證方式&#xff0c;簡單的說就是需要你輸入用戶名和密碼才能繼續訪問。對于Basic Auth的概念不過多的進行介紹&#xff0c;直接進入如何實現的過程。 Basic Auth說白了就是賬號和密…

canvas高斯模糊算法

對于模糊圖片這個效果的實現&#xff0c;其實css3中的filter屬性也能夠實現&#xff0c;但是這個屬性的兼容性不是很好&#xff0c;所以我們通常不用這種方法實現&#xff0c;而使用canvas配合JS實現。 <span style"white-space:pre"> </span>//高斯模糊…

word中插入公式的快捷鍵_如何使用插入鍵在Word中插入復制的內容

word中插入公式的快捷鍵In Word, the “Insert” key on the keyboard can be used to switch between Insert and Overtype modes. However, it can also be used as a shortcut key for inserting copied or cut content at the current cursor position. 在Word中&#xff0…

微軟終于為 Visual Studio 添加了內置的 Markdown 編輯器

微軟終于為 Visual Studio 添加了內置的 Markdown 編輯器。根據官方博客的介紹&#xff0c;由于收到許多用戶的反饋&#xff0c;微軟決定為 Visual Studio 添加 Markdown 編輯器。開發者下載最新的 Visual Studio 17.5 第 2 個預覽版就能夠使用 Markdown 編輯功能&#xff0c;無…

【經驗分享】Hydra(爆破神器)使用方法

這個也是backtrack下面很受歡迎的一個工具 參數詳解&#xff1a;-R 根據上一次進度繼續破解-S 使用SSL協議連接-s 指定端口-l 指定用戶名-L 指定用戶名字典(文件)-p 指定密碼破解-P 指定密碼字典(文件)-e 空密碼探測和指定用戶密碼探測(ns)-C 用戶名可以用:分割(username:passw…

【東軟實訓】SQL多表鏈接

如果一個查詢同時涉及兩個以上的表&#xff0c;則稱之為鏈接查詢&#xff0c;鏈接查詢是關系數據庫中最主要的查詢&#xff0c;主要包括等值鏈接查詢、非等值鏈接查詢、自身鏈接查詢、外鏈接查詢和復合條件鏈接查詢。 這篇博文我們來對多表鏈接進行學習。 Outline 鏈接的基本概…

博鰲“‘AI+時代’來了嗎”分論壇,嘉賓們有何重要觀點?...

雷鋒網(公眾號&#xff1a;雷鋒網)3月27日消息&#xff0c;正在進行中的博鰲亞洲論壇2019年年會&#xff0c;于2019年3月26日至29日在中國海南博鰲舉辦。今年博鰲論壇的主題為“共同命運 共同行動 共同發展”。今天&#xff0c;在主題為《“AI時代”來了嗎&#xff1f;》分論壇…

一款統計摸魚時長的開源項目

對于我們程序員&#xff0c;在工作中一天8小時&#xff0c;不可能完全在寫代碼了&#xff0c;累了刷刷論壇、群里吹吹牛&#xff0c;這都是非常正常的。雖然一天下來&#xff0c;可能我們都可以按時完成工作&#xff0c;但是我們不知道&#xff0c;時間都花在哪里了&#xff0c…

saltstack 主題說明

轉載于:https://www.cnblogs.com/40kuai/p/9335869.html

基于spring boot 的ssm項目的簡單配置

2019獨角獸企業重金招聘Python工程師標準>>> 我前面的帖子有介紹spring boot的簡單搭建&#xff0c;現在我再講講spring boot的簡單配置 首先&#xff0c;項目結構 啟動類 RestController 注解相當于ResponseBody &#xff0b; Controller合在一起的作用。 Sprin…

nest 架構_如何與其他人分享您的Nest Cam Feed

nest 架構Your Nest Cam can help you keep an eye on your home from anywhere you are, but more eyes you trust to watch your stuff is more comforting. If you want someone else to check in once in a while, you can share your Nest Cam feed with a simple, passwo…

關于公司內部DNS的整改建議

文章背景&#xff1a;由給leader的郵件而來&#xff0c;在文章末尾另加了一些補充&#xff08;見FAQ&#xff09;。原主題&#xff1a;關于公司內網DNS服務器中的u-sooc.com域名調整建議 建議&#xff1a;將公司內部DNS服務器&#xff08;Windows Server 2008 R2&#xff09;所…

.Net 和Assembly下滑其它回升,TIOBE編程語言2022年12排行榜

楔子TIOBE編程語言排行榜一般反應的是語言的生態&#xff0c;個人比較喜歡這個排行。來看下2022年最后一個月12月&#xff0c;最后一天,TIOBE的排行榜單。榜單分析這里只看下前10名的編程語言&#xff0c;里面非常顯眼的是所有的語言都增加了生態環境&#xff0c;包括不被看好的…

Haproxy安裝與配置

Haproxy安裝與配置 有關高負載均衡的軟件&#xff0c;目前使用比較多的是haproxy、nginx和lvs。下面我們就開始學習haprxoy這款軟件。 1、Haproxy概念 1.1、haproxy原理 haproxy提供高可用性、負載均衡以及基于TCP(第四層)和HTTP&#xff08;第七層&#xff09;應用的代理&…

刪除word中所有的表格_如何在Word中刪除表格

刪除word中所有的表格If you’ve inserted a table in Word and you now want to delete it, you may have found it’s not all that straightforward to delete the entire table without deleting other content around the table. We’ll show you a couple of ways around…

Java web application——基礎

概述 一個WAR文件包含了構成一個Web應用程序所需要的文件。WAR文件作為一個單元部署在一個或多個WebLogic Server實例上。 WebLogic Server上的Web存檔始終包含以下文件&#xff1a; 一個servlet或Java Server Page&#xff08;JSP&#xff09;&#xff0c;以及任何幫助程序類。…

Jenkins在windows平臺下,讓Powershell和批處理可以拉起進程并保持

&#x1f4e2;歡迎點贊 &#xff1a;&#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff0c;賜人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原創&#x1f4e2;作者格言&#xff1a;無盡的折騰后&#xff0c;終于又回到…