貯存

Android 外部存儲 HAL 圖標

隨著時間的推移,Android 已經發展到支持各種存儲設備類型和功能。所有版本的 Android 都支持具有傳統存儲的設備,其中包括便攜式和模擬存儲。便攜式存儲可以由物理介質(如 SD 卡或 USB)提供,用於臨時數據傳輸/文件存儲。物理媒體可能會在設備中保留很長時間,但不會與設備綁定,並且可能會被移除。從 Android 1.0 開始,SD 卡就可以作為便攜式存儲設備使用; Android 6.0 增加了 USB 支持。模擬存儲是通過模擬層暴露一部分內部存儲來提供的,並且從 Android 3.0 開始就可以使用。

從 Android 6.0 開始,Android 支持由物理媒體(如 SD 卡或 USB)提供的可採用存儲,這些存儲經過加密和格式化,可以像內部存儲一樣使用。可採用的存儲可以存儲所有類型的應用程序數據。

權限

對外部存儲的訪問受到各種 Android 權限的保護。從 Android 1.0 開始,寫訪問受到WRITE_EXTERNAL_STORAGE權限的保護。從 Android 4.1 開始,讀取訪問權限受到READ_EXTERNAL_STORAGE權限的保護。

從 Android 4.4 開始,外部存儲設備上文件的所有者、組和模式現在基於目錄結構進行合成。這使應用程序能夠在外部存儲上管理其特定於包的目錄,而無需它們擁有廣泛的WRITE_EXTERNAL_STORAGE權限。例如,包名為com.example.foo的應用程序現在可以在沒有權限的情況下自由訪問外部存儲設備上的Android/data/com.example.foo/ 。這些合成權限是通過將原始存儲設備包裝在 FUSE 守護程序中來實現的。

從 Android 10 開始,面向 Android 9 及更低版本的應用默認使用舊版存儲,並且可以選擇使用獨立存儲。以 Android 10 為目標且默認使用獨立存儲的應用可以暫時選擇退出。使用控制存儲模型的清單屬性requestLegacyExternalStorage來更改默認狀態。

由於READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE權限均受軟限制,如果安裝程序未將應用列入白名單,則該權限僅控制對聽覺和視覺集合的訪問,而無法訪問 SD 卡。即使應用程序請求舊版存儲,這也適用。有關硬限制和軟限制的更多信息,請參閱Android 10 中的硬限制和軟限制。

如果安裝程序將權限列入白名單,則以舊模式運行的應用程序將獲得非隔離權限行為。該權限控制 SD 卡訪問以及聽覺和視覺收藏。當應用以 Android 9 或更低版本為目標且未選擇加入隔離存儲,或者應用以 Android 10 為目標並選擇退出時,就會發生這種情況。

白名單狀態只能在安裝時指定,在安裝應用程序之前無法更改。

有關設置READ_EXTERNAL_STORAGE權限的更多信息,請參閱PackageInstaller.SessionParams類中的setWhitelistedRestrictedPermissions()

運行時權限

Android 6.0 引入了一種新的運行時權限模型,應用程序在運行時需要時請求功能。由於新模型包含READ/WRITE_EXTERNAL_STORAGE權限,平台需要動態授予存儲訪問權限,而無需終止或重新啟動已經運行的應用程序。它通過維護所有已安裝存儲設備的三個不同視圖來做到這一點:

  • /mnt/runtime/default顯示給沒有特殊存儲權限的應用程序,以及adbd和其他系統組件所在的根命名空間。
  • /mnt/runtime/read顯示給具有READ_EXTERNAL_STORAGE的應用程序(為 Android 10 設置LEGACY_STORAGE
  • /mnt/runtime/write顯示給帶有WRITE_EXTERNAL_STORAGE的應用程序

在 Zygote 分叉時,我們為每個正在運行的應用程序創建一個掛載命名空間,並將適當的初始視圖綁定到適當的位置。稍後,當授予運行時權限時, vold會跳轉到已經運行的應用程序的掛載命名空間並綁定將升級後的視圖掛載到位。請注意,權限降級總是會導致應用程序被終止。

用於實現此功能的setns()功能至少需要 Linux 3.8,但補丁已成功向後移植到 Linux 3.4。 PermissionsHostTest CTS 測試可用於驗證正確的內核行為。