存储

Android external storage HAL icon

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 6.0 引入了一种新的运行时权限模式,在该模式中,应用可在运行时根据需要请求功能。由于新模式包含 READ/WRITE_EXTERNAL_STORAGE 权限,因此平台需要动态授予存储访问权限,而不会终止或重新启动已运行的应用。通过维护所有安装存储设备的三个不同视图可实现该模式:

  • /mnt/runtime/default 是向无特殊存储权限的应用以及 adbd 和其他系统组件所在的根命名空间显示。
  • /mnt/runtime/read 是向具有 READ_EXTERNAL_STORAGE 的应用显示
  • /mnt/runtime/write 是向具有 WRITE_EXTERNAL_STORAGE 的应用显示

在 Zygote 进行 fork 操作时,我们会为各运行应用创建装载命名空间,并将相应的初始视图挂载到位。稍后,当授予运行时权限时,vold 将跳转到已运行应用的装载命名空间,并将升级后的视图挂载到位。请注意,权限降级定会导致应用被终止。

用于实现此特性的 setns() 功能至少需要运行 Linux 3.8,但补丁程序已反向移植至 Linux 3.4。PermissionsHostTest CTS 测试可用于验证内核行为是否正确。

在 Android 6.0 中,第三方应用无权访问 sdcard_rsdcard_rw GID。相反,访问通过仅为该应用装载适当的运行时视图来控制。用户间交互使用 everybody GID 来阻止。