系統角度解讀Android P新特性

引言

2018年3月8日,谷歌發佈了Android P的預覽版,預計今年的Q3季度發佈final release版本,有不少文章從開發者角度介紹了Android P的新特徵,初步來看給感覺這次大版本似乎並沒有什麼改變。接下來,將從系統Treble,System,Framework,Runtime, Security等多方面來解讀一下Android P的變化。

Treble計劃

Treble計劃是一個非常重要的變革,對系統層面的影響很大。Google每發佈一個Android大版本,到廠商和APP的適配,過程是漫長的,每一次大版本適配工作的艱難廠商最能體會,各種兼容性問題。正如去年發佈的Android O,目前Android O機型用戶量比較小,APP都沒能快速跟進把targetSdk適配到O的情況下,Android P又即將到來,Android系統的碎片化一直是一個痛點。該計劃的核心主旨是讓系統與硬件相關的解耦,加快系統升級速度。Treble始於Android O,到Android P又得以進一步完善。

接下來,來看看Treble在整個Android系統的位置。

treble.jpg
  • Product: OEM相關定製,主要包括Apps,產品sysprops等
  • System:Android系統的Framework和Daemons
  • Treble Interface: Treble接口
  • Vendor: 硬件相關
  • ODM: ODM相關定製,比如VINTF支持

最中間Treble Interface組成成分,在Android O添加的接口:C++依賴(使用VNDK),IPC調用(使用HIDL),SELinux,通用Kernel接口,Android Verified Boot(AVB);到Android P新增接口:Java依賴(使用System SDK),系統Properties。從圖中可以看出Treble計劃是希望底層Vendor用舊版本,也能支持System層升級爲新版本,從而保證Android大版本可快速升級。

這裏需要注意,System Property兼容性對於treble來說是非常糟糕的,它允許平臺和Vendor之間通過非穩定通道進行跨進程通信,這與treble的分離解耦背道而馳。
爲此,treble計劃通過分離properties到platform和vendor。platform進程只能訪問平platform屬性,vendor進程只能訪問vendor屬性, 當然也是允許platform屬性去暴露給vendor進程。

  1. 所有platform對外暴露的屬性位於system/sepolicy/public/property_contexts,Vendor無法訪問其他的平臺屬性;
  2. 所有可用於vendor init腳本的屬性位於system/core/init/stable_properties.h,Vendor init腳本不能使用其他的平臺屬性來作爲
    action triggers。
  3. Vendor或者ODM屬性必須有自己的命名空間,比如vendor., ro.vendor, persist.vendor等
  4. vendor init使用vendor_init域名,保障只使用vendor相關權限,不可訪問system-only的屬性

VINTF(Vendor Interface)被分離成硬件無關(Framework)和硬件相關兩部分。爲了進一步規範化系統架構,定義了CKI(Common Kernel Interface)作爲通用系統鏡像必須依賴的內核接口集,並且對Kernel分支精簡也進行了有效的精簡。
VTS會測試HAL,Kernel, VNDK的可靠性,CTS測試通用系統接口,framework feature。從Android O以後就強制要求,通過CTS/VTS則會爲system解耦合的適配提供了保障。

Treble語境中,Vendor是指片上系統的HAL層和外圍設備,不依賴於硬件的軟件則不屬於Vendor;VNDK是指Vendor用於實現HAL層所提供的系統庫。

  • platform和Vendor的構建是相互隔離的。
  • platform lib對應 system.img
  • vendor lib對應 vendor.img
  • 大多數情況下,Vendor lib跟系統核心不能相互使用;Vendor lib不允許dlopen私有的系統庫
  • 合作伙伴不允許爲自己的產品在VNDK新增lib,只能貢獻到AOSP
VNDK.jpg

這一切都是爲系統庫與Vendor庫之間的解耦合,在Android P上採用該方案,則下一個大版本Android Q更新,可以直接將新的System Q加上老Vendor P,組成新版本Android。

其中VNDK + Framework libs組成system.img, Vendor libs組成vendor.img。

Android P新添加命名空間namespace:

  • System命名空間/system/lib/;
  • Vendor命名空間有/system/lib/vndk,/system/lib/vndk-sp,/vendor/lib/vndk,/vendor/lib/vndk-sp

System

1. 存儲性能提升

FDE用於Android 6.0, FBE用於Android 7.0,並且會創建DE和CE兩個目錄,提供更好的用戶體驗和隱私安全。 FDE很快會被徹底移除。
另外,未來會有更快的加密算法。

文件系統

文件系統配額從Android 8.0開始支持,三個主要目標是

  • 當打開設置時能快速計算存儲使用情況,提供更好的用戶體驗
  • 更快和更公平的cache管理,通過quotas來管控濫用的app
  • 通過配額方式來限制應用濫用存儲空間

Fair cache策略:

  • 分配cache配額給每個App(基於他們使用的頻率),刪除最老的cached文件,直到有足夠的空閒空間;

  • 最佳實踐:定期調用新方法以保證系統有機會去刪除緩存文件,可以follow PackageInstaller,DownloadManager和DocumentsUI。
    限制濫用app:

  • 設備應該卸載惡意app,或者刪除大文件

  • 避免設備卡在循環的重啓過程

  • 阻止app使用block90%, 或者inodes50%

  • exFAT:Google沒有資源支持相關的更新工作,只有會部分補丁;

  • vold:跟fw通信方式,由socket調整爲binder方式,用於提高性能;這是繼installerd之後的再一次由socket轉變成binder模塊;

  • TRIM: 該過程會運行f2fs GC操作,並且在夜間空閒時間來被調度執行;

  • FUSE: 已被刪除,採用sdcardfs, 後續會有esdfs用於更深遠的優化

  • 更快的文件拷貝: FileUtils.copy,比如純userspace的方式快35~50%

  • FDE,FUSE, ASECs這些都被刪除。

2. 簡述Kernel

  • w的feature後續依賴Kernel 3.18或之後的版本,3.10將不再維護。另外Kernel 4.14已推到AOSP;
  • ION: libion在Android P上已支持新的kernel ion接口,強烈建議 使用libion,而非直接使用ion ioctl調用
  • kernel + clang: 強烈建議採用clang 5.0或之後版本,出錯信息提供精準定位,佔用內存和編譯速度快,而gcc有一定的歷史問題。
  • sdcardfs: android O默認的文件系統,ro.sys.sdcardfs=1,Android O上默認的文件系統是sdcardfs,但允許關閉,回退到FUSE。而Android P則計劃直接刪除FUSE,很快會更新一版sdcardfs。對於文件系統,即便不使用sdcardfs,也強烈推薦使用基於內核的文件系統,而非用戶空間。

3. LMKD調整

基於內核的LMK缺點:

  • 依賴於硬編碼的剩餘內存限制,而非基於內存緊張情況來調整;
  • 廠商定製化比較多,也就意味着原有的設計比較死板,不適合增加policy定製,沒有以group方式來殺進程
  • 在slab shrinker API中插樁,Shrinkers本應該快速drop不再使用caches並退出,以避免拖慢內存掃描進程。
    但事實上,lmk執行的工作量包括搜索目標進程以及殺掉它們,這個過程並非快速完成的動作
  • 有可能出現把重要的進程殺掉,而非重要進程並沒有被殺
  • 從內核4.12中會移除lmk;

替代方案:用戶態LMKD + memory cgroups

  • 可打造更智能的基於內存壓力的殺進程策略
  • memory cgroups,內存壓力事件,內存記賬功能,額外的控制類似relaim和swappiness
  • 能被更方便的記錄日誌和track
  • 該方案的挑戰:每個app需要有內存記賬;殺進程組耗時;cgroups之間的task轉移代價比較高;
  • 相應解決方案:最新內核已降低內存開銷,應用啓動時間增加了3%,在多個小的LRU隊列並不高效;
  • 殺進程組耗時的問題,通過將殺進程過程移到AMS鎖之外
  • LMKD的殺進程組委託給ActivityManager

用戶態LMKD策略:

  • 通過ro.config.low_ram屬性來劃分低內存設備和高性能設備
    • 低內存設備:中等內存壓力出現得比較常見,殺進程主要針對medium和critical內存壓力情況,配置oom_adj_score,內存壓力基於swap使用情況。殺進程策略會延遲,儘量保持服務處於運行中的狀態
    • 高性能設備:優先考慮性能和儘可能留有更多內存來優化用戶體驗。殺的策略會提前,一次會殺多個進程以保證內存處於低壓力狀態,更加激進地釋放內存以保持系統處於低內存壓力的狀態

未來

  • 提高殺進程策略,基於輸入信號(可用內存,task大小,內存壓力值,內存壓力事件的頻繁成都)
  • 合併殺進程策略,提供更多controll機制
  • 探索殺的時機,以及內存壓力的潛力
  • 配合cgroups v2

4. F2FS

sdcardfs和fuse纔是一個層面的東西,sdcardfs比fuse的的性能更好,對同一文件的操作,fuse需要經歷6次用戶態與內核態的切換,而sdcardfs只需要兩次。對於fuse可以使用各種文件系統,比如ext3, ext4, f2fs.

(F2FS,Flash-Friendly File System)文件系統重要特性

  • 後臺清理:當文件系統碎片化比較嚴重的時候,讀寫速度會有所下降,開啓一個反碎片的後臺線程來清理文件碎片;
  • 異步discard:Discard文件系統的淘汰存儲空間,對於減少閃存過度GC是很有必要的,當同步的discard對用戶來說會有比較大的延遲,故採用異步Discard;
  • 原子寫:SQLite是Android默認的數據庫,通過管理記錄文件來保障數據安全,這會帶來大量冗餘的寫和同步操作;原子寫能有效減少記錄文件;

F2FS相比ext4在文件順序寫、隨機寫以及SQLite方面有較大幅度的提升。Google將持續調整F2FS的性能與穩定性方面的表現。

5. 性能

在Android O上將Binder大鎖拆分爲更細粒度的鎖,便真正解決了binder鎖競爭問題。

  • 內核驅動代碼在必要時可採用RT調度器,避免在驅動裏有長時間地禁用搶佔
  • 建議:
    • 如果可能,建議使用mem cgroups
    • userdata文件系統,建議採用f2fs
    • 關閉不需要的內核配置項
    • 移除不必要的日誌
    • 在早期的文檔中建議低內存設備要開啓KSM,之後的版本不要使用KSM

P上更加註重相同性能下如何改進功耗,EAS作爲通用的基於功耗模型和性能數據的CPU調度算法,而非tuning的方式。
爲什麼Android採用EAS調度算法呢?需要一個標準的結合功耗和性能的調度器,能通過Framework來調整調度策略,這裏需要考慮資源負載均衡、大小核、cpufreq、 governor、減少大核的使用、平衡功耗問題,2018.5完成EAS r1.6版本。

Framework

1. AMS

從Android P開始,只有當Intent flag中指定了FLAG_ACTIVITY_NEW_TASK,才允許在非Activity場景啓動Activity。
APP必須擁有FOREGROUND_SERVICE權限,才允許使用前臺服務,否則會拋出異常。

目前很多APP開發者們對Android O的一些後臺限制行爲不太瞭解這些變更,遇到問題可能誤以爲系統問題,所以這裏說到這順便提一下關於Android O對後臺行爲的一些管控。

  • 後臺服務(Background Service)限制

    • 當進程處於後臺1分鐘後會進入idle狀態,系統停止其後臺服務,也就意味着應用處於後臺必須1分鐘內處理完收尾工作,不允許在後臺長時間監控系統,從而節省功耗;對於應用後臺執行用戶不可感知的操作,官方推薦使用JobScheduler
    • 後臺進程不允許通過startService方式啓動服務,否則當targetSdk>=26的情況下會拋出IllegalStateException;
    • 對前臺服務(Foreground Service)不會有這個限制,因爲前臺服務都會掛一個前臺通知對用戶來說是可見的。Android O新增startForegroundService(),用於啓動前臺服務,但有一個限制條件就是應用必須服務啓動後5秒之內調用startForeground(),否則會拋出ANR
  • 廣播(Broadcast)限制:

    • 應用無法使用其清單註冊的大部分隱式廣播,但部分隱式廣播是被允許的, 比如BOOT_COMPLETED, LOCALE_CHANGED等。這樣做是爲了省電和性能,防止大量APP通過監聽各種廣播來拉起自己。
    • 清單註冊的顯式廣播和動態註冊的隱式廣播依然可以正常工作。

2. PMS

重構Package Manger,減少核心服務的代碼複雜度,將permission,intent等代碼移到單獨的類,
將user management,dex,shortcuts等不相關代碼移到子包;儘可能操作本地數據,避免加鎖;同時增加單元測試。

PMS在Android O主要改動是優化啓動時間,將操作儘可能並行化執行,在Android P上主要改動是掃描過程scanPackageOnly(),
下一步提取更多的子組件和類,比如Intent resolution, package verification, dexopt等,減少修改對象成員的方法。

3. WMS

在Android O上,結構化窗口對象模型和容器層次結構, 提高CTS覆蓋率並引入單元測試,SurfaceFlinger中引入層級結構用於SurfaceView,引入Task快照。在Android P上,繼續提升創建對象模型,同步APP Transitions,WindowScope工具,

過度使用Stack ID, Stack管理着類似的task和activity,特定的窗口模式,例如HOME_STACK_ID,FULLSCREEN_STACK_ID,FREEFORM_STACK_ID,這就導致同一個Stack的task和activity不允許有不同的窗口模式。新的方案允許有多個WindowContainers,窗口模式不再受限於Stack ID。

採用同步的APP Transitions, animations的過程可不再需要WMS大鎖。另外Transitions,WindowScope工具是一個類似於systrace的工具,可用於方便查看WindowManager和SurfaceFlinger,僅在userdebug版本開啓,對性能影響較小。

4. 續航提升

之前關於續航方面,有JobScheduler, Doze, 限制隱式廣播,後臺服務和定位限制,緩存wakelock釋放等功能,
一直以來Google在功耗方面沒有從整體上的策略,不同OEM往往會有不同的策略針對功耗,比如Force stop app,
kill activity/service等。這次Android P在功耗方面也是重點,Google計劃在Android P上採用機器學習的思路來預測用戶使用習慣,來做省電優化。
從而把APP分爲四類Active, working_set,frequent, rare,劃分到不同bucket的app則採取對Jobs,Alarms,Network, FCM等限制策略。

目前很多應用爲了後臺存活,都掛fg-service,其實Google,包括廠商都非常不建議開發者一直這樣使用的,應該儘量剋制,只要需要的場景使用,比如後臺導航、後臺播放音樂。
這也是爲什麼fg-service一定要顯示通知,爲的是讓用戶可知應用的行爲,對於不該後臺活動的依然掛前臺通知,那麼用戶可能會主動殺它,甚至卸載。

5. 機器學習

在Android 8.1中引入神經網絡API,提供Android內置的機器學習,在Android P中又進一步擴展和改進TensorFlow.
在Android P上採用AI預測用戶行爲來進行更智能化的省電策略,在UI搜索界面也使用到機器學習,AI正在逐步強化Android系統

Dynamic App,需應用商店支持,資源文件,配置,語言,App內部基於版本格式的信息等都可以採用Dynamic App來精簡APK尺寸。
Autofill:平臺、插件、app、瀏覽器,一套完整的自動填充框架解決方案

6. Location

電話體驗
提升打電話的用戶體驗,擴展APIs從而支持不同APP的電話併發,Telecom可跟蹤所有的活動來電,但只有一個應用可獲取焦點。另外,
調整SIM狀態改變的廣播,SIM_STATE_CHANGED改爲SIM_CARD_STATE_CHANGED和SIM_APPLICATION_STATE_CHANGED廣播。
也同步調整了TelephonyManager。

活動檢測
活動檢測會結合傳感器和聲音數據,能識別走路、跑步、騎車、開車、上下樓梯,甚至要區分使用者是在汽車、地鐵、火車,還是摩托車,也能識別睡眠模式,
當AR檢測到處於開車模式,則停止通知以避免打擾開車人員。爲系統提供使用者活動狀態轉換的API

室內導航
一直以來無法做到精準的WIFI室內定位,次次Android P系統支持了IEEE 802.11mc WiFi協議,室內導航功能即將到來,應用能使用室內定位,爲定位服務提供便利。

CHRE
優化功耗就意味着需要儘可能少的喚醒AP,比如Doze模式,後臺定位限制模式。定義一個Context Hub運行時環境,在該環境下的CPU不允許直接運行Java/Linux,只允許執行特殊的功能。
在Android P實現了Context Hub Service,使用起來更加簡單。後續可以有always-on,低功耗模式

Runtime

1. ART和libcore

在安裝、更新、OTA的時候ART需從APK裏提取壓縮過的dex並進行校驗,這樣既浪費空間,也浪費CPU時間。
爲此,正在做的方案是採用未壓縮的dex文件,商店將會對其進行Java校驗並將校驗結果直接在安裝過程使用。
對於dex文件開始採用一個新的緊湊的格式,減少對內存和存儲空間的使用,更加智能的佈局優化,更少的閃存讀取。

關於調試方面,使用JVMTI來替代ART debugger,提供更多的擴展功能,包括斷點、異常等事件,本地變量審查,字段監測,類的重定義。

Backtraces使用Java上下文來顯示,省去使用addr2line來轉換的一個過程,方便調試分析問題。例如

backtrace.png

Kotlin作爲Android官方正式語言,其性能並不會比Java執行慢

Profiles in the Cloud:
從N開始使用profile方式編譯,對於存儲空間、內存、功耗、CPUs使用率都有益處,但目前profile只是本地的方式,
在優先之前仍需要等待獲取profile。未來收集用戶的profile,並上傳到雲端(Google play),在安裝時從雲端獲取profile直接使用到新用戶。
大概能提升20%的冷啓動性能。

core lib
升級libcore代碼到OpenJDK 9。APP棄用策略,Android將添加支持的最低版本,當targetVersionSdk<17的app則會彈出警告框。
從bootclasspath中移除Apache HTTP庫、JUnit

2. Soong編譯系統

採用Soong來編譯Java,從GNU Make移植到Soong

跨版本構建過程:

soong.png

Android P到底可見的Android.bp,所有依賴必須使用android.bp,androidmk工具可用於將make文件轉換爲Android.bp文件;

3. 私有API

Android P在運行時強制限制應用通過反射方式來操作被標記爲@hide的類、方法、屬性。
將API分爲4類:白名單、灰名單、深灰名單、黑名單;當API屬於白名單則不限制,灰名單(targetSdk ≥P)則警告,黑名單則
拋出NoSuchFieldException/NoSuchMethodException異常。對於深灰名單,介於灰名單和黑名單之間,取決targetSdk,
當(targetSdk ≥P)按黑名單方式處理,當(targetSdk <P)按灰名單方式處理。
對於黑名單隻允許平臺APP使用,對於灰白名單的API雖然不會直接拋出異常,但不再保證跨版本的兼容性,這樣限制是爲了後續新版本能更快地完成適配。

Google之所以要設計灰白黑名單,也是爲了給應用一個過渡時機,也給Android一個完善公開API的機會,對於某些很重要的@hide接口,可能也會考慮適當增加公開接口,另外那些API會被第一批加入黑名單,還需拭目以待。對於AOSP的黑名單和深灰名單將放入CTS測試,進而限制廠商不能輕易修改名單。

關於兼容性測試,Google目前有CTS/VTS/GTS,其中CTS主要測試API行爲,VTS針對Treble計劃以及測試HW實現,GTS針對GMS需求和分銷協議,
很快Google還會推出STS,用於隱私測試。從Top應用的測試數據來看,目前國內大多數的APP都存在兼容性問題,問題主要集中在熱修復、混淆、加固以及依賴internal API。

另外,@SystemApi不再向後兼容,另外幾乎所有的系統API都需要權限。
/vendor/priv-app將在Android P上支持,權限會被限制有vendorPrivileged標識的權限。

Security

將所有網絡流量從明文轉向TLS,更改網絡安全性配置 (Network Security Configuration) 的默認值,以阻止所有明文流量。
爲保護用戶隱私,當應用UID空閒時,斷開應用對攝像頭、話筒、傳感器的使用,如果應用強制使用則會產生錯誤,從而進一步防止流氓應用後臺手機隱私數據。

FBE加密:FBE將會更容易支持高端元數據加密的設備,以及對sdcard的支持。對於OEMs能夠更簡單地移植。對於低端設備,更快速的算法,適合所有機型的移植

總結

  • Android P的Treble計劃爲後續Android大版本可快速升級提供支撐;
  • 採用全新的Soong編譯系統,將Android.mk全面替換爲Android.bp;
  • 私有API的限制進一步規範化Android生態,但同時也面臨着生態圈中大多數的APP都不可用的風險挑戰;
  • 默認採用sdcardfs提升存儲性能,F2FS相比ext4在文件順序寫、隨機寫以及SQLite方面有較大幅度的提升;
  • Framework逐步優化PMS、WMS大鎖,未來應該還優化AMS鎖;
  • 逐步試水AI技術,增強對APP後臺管控,以提升系統續航能力。

總之,Google一方面從系統層面不斷優化Android系統;另一方面致力於改善APP生態,不斷加強對非友善APP的管控,減少其對系統性能與續航的影響。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章