系統角度解讀Android P新特性

2019/3/30

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支持
     

鄭州APP開發公司,就找河南天頻信息有限公司

最中間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的屬性
     

鄭州APP開發公司,就找河南天頻信息有限公司

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
 

鄭州APP開發公司,就找河南天頻信息有限公司

這一切都是為系統庫與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文件;

鄭州APP開發公司,就找河南天頻信息有限公司

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的管控,減少其對系統性能與續航的影響。

浙江体彩61中奖规则