41

Chrome OS上的Android系统

 4 years ago
source link: https://paul.pub/android-on-chrome-os/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Chrome OS上的Android系统

Chrome OS上的Android系统

Posted on Sep 20, 2019

 OS  ChromeOS  Android  APK  Container  VM


Chrome OS是Google公司开发的基于Chrome浏览器的操作系统。本文会讲解Chrome OS对于Android系统支持方面的内容。

bg.JPG

Chrome OS与Android都是Google公司开发的操作系统。前者发布于2011年,后者发布于2008年。

当然,大家可能还知道Google的另外一个操作系统,叫做Fuchsia。在今后的文章中,我们也会谈到。

距离Android发布已经超过10年时间,它在移动互联网时代取得了巨大的成就。与此同时,Chrome浏览器也一样非常的成功。相较而言,Chrome OS却仍然不温不火。

目前,Chrome OS主要在以下几种设备上运行:

  • Chromebooks
  • Chromeboxes
  • Chromebits

本文不想对比Chrome OS或者Android系统那个更好,也不会深入讨论Chrome浏览器或者 Chrome OS的具体实现。只将重心发在Chrome OS对于Android App的支持上。因为对于很多人来说,要么是Android平台的开发者,要么是Android系统的用户。

阅读本文需要对Android系统实现有一定的了解,你可以访问Android官方网站获取相应的知识:

或者阅读我之前写过的一些文章:AndroidAnatomy

获取Chrome OS源码

通过下面的命令可以获取Chrome OS的源码:

mkdir chromeos
cd chromeos
repo init -u https://chromium.googlesource.com/chromiumos/manifest.git
repo sync

上面的命令会将Chrome OS的源码下载在chromeos目录中。完整的源码大小超过20个G,因此可能需要比较长的时间才能完成下载。

如果你想要编译Chrome OS或者对Chrome OS系统开发有兴趣,下面两个文档是一个比较好的开始。

Chrome上的Android应用

Chrome上对于Android应用的支持经历了三个项目和阶段。

项目名称 开发时间 状态 特点 其他说明
ARC 2014年 已废弃 支持各桌面平台的Chrome浏览器 需要Android开发者对接,并存在安全问题
ARC++ 2016年 正在使用 Chrome OS专用,通过Linux容器运行 安全性有所提升,但仍然不够
ARCVM 2019年 开发中 独立虚拟机,更加安全 不确定是否会与ARC++项目合并

ARC是 App/Android Runtime for Chrome 的缩写。

ARCVM 是 ARC Virtual Machine 的缩写。

由于ARC项目已经废弃,因此本文不再讨论。

下面仅对另外两个项目做一些介绍。

ARC++ 项目

前面已经看到,ARC项目是为Chrome浏览器设计的。由于浏览器的安全模型与原生系统有很大差异,因此支持Chrome浏览器的应用需要开发者进行特定的修改。这对应用开发者来说,无疑是增加了负担。

因此ARC++项目的设计目标包括:

  • 能够直接访问Google Play商店上的应用
  • 尽可能少的修改 Android Framework
  • 不破坏Chrome OS安全性
  • 维持Chrome的更新模型

在Chrome OS工程中,ARC++项目的源码并非集中在一起,它们分散在多处。

Android container

整体来说,ARC++项目的实现机理是:将Android系统运行在基于Linux namespace的容器中。以此达到与宿主系统(Chrome OS)相隔离的目的。

Linux namespace 是内核提供的一个特性。它通过命名空间的形式将资源隔离,使得不同集合的进程看到不同集合的资源。这项技术也是Linux上容器(例如:lxc 和 docker)实现的基础。

Linux 提供了 7 种类型的命名空间:

  • Cgroup
  • Network
  • Mount

关于Linux namespace,读者可以通过下面两个链接了解更多信息:

run_oci 与 config.json

在 Chrome OS 中,有一个名称为 run_oci 的模块,它是一个小巧的容器运行时,它会读取名称为 config.json 的配置文件来完成Android容器的初始化工作。

config.json 中的描述了需要挂载的文件系统,命名空间,设备节点,cgroup配置以及继承的能力。你可以点击链接查看这个文件中的内容。

Android container的启动与退出

config.json 文件中包含了下面这段配置。

"process": {
	"terminal": true,
	"user": {
		"uid": 0,
		"gid": 0,
		"additionalGids": [5005]
	},
	"umask": 0,
	"args": [
		"/system/bin/init",
		"second_stage"
	],
	"env": [
		"INIT_SELINUX_TOOK=1500",
		"INIT_STARTED_AT=1000",
		"PATH=/sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
	],
	...

对Android有所了解的读者在看到/system/bin/init应该会觉得很熟悉。

在Android系统上,init进程负责了整个系统的启动逻辑。它会读取 /init.rc 文件完成系统的初始化工作,这其中包含启动 Android 系统中最重要的一些进程,例如:zygotesystem_serversurfaceflinger等。

如果你不理解这里的内容,请熟悉一下 Android Init Language,或者阅读我之前写过的文章:Android系统启动:init进程与init语言

Chrome OS 上 Android container 启动和退出的流程如下图所示:

boot-process.png

借助于run_oci,可以很方便的控制Android容器的入口。这样无论是在开发阶段还是运行阶段,Android系统和Chrome OS都很好的解耦和分离开了,这也就非常的便于维护。这种做法是我们在做软件设计(尤其是大型软件系统)时非常值得借鉴学习的。

在Linux容器的基础上,Android的相关进程都已经启动。接下来还需要对接用户界面的图形系统。

图形系统的内容包括:

  • 负责应用窗口的创建
  • 负责应用窗口的状态变化(例如:移动,改变尺寸)
  • 负责图形内存的分配
  • 负责图形的合成
  • 负责图形的渲染
  • 负责输入事件处理

对于 Android 图形系统不熟悉的读者,可以先看这里的文章:AOSP: Android Graphics Overview

Android的图形系统结构如下:

ape_fwk_graphics.png

在Android系统上,图形系统的主要组件包括:

  • Gralloc:负责分配图形缓冲。
  • HWComposer:通过硬件确定缓冲合成的最有效方法。
  • SurfaceFlinger:接受来自多个源的数据缓冲,将它们合成并将它们发送到显示器。
  • WindowManager:负责创建和管理窗口。

从Android 4.0开始,Android 应用使用的Canvas API通常都会通过硬件加速。另外,还有一些应用会使用 OpenGL ES,甚至使用更新的 Vulkan 接口。

Android系统上的所有界面都通过 Surface 渲染出来。应用程序借助于 Surface 生成应用的界面,并将图形缓冲放入队列中,这些缓冲队列由SurfaceFlinger处理。在底层,Surface的图形缓冲通过gralloc分配。

对于窗口管理来说,Android N(7.0)已经支持多窗口。在《Android 7.0中的多窗口实现解析》一文中,我们已经了解到,Android 的多窗口支持下面三种模式:

  • 画中画模式
  • Freeform 模式

有了这些背景知识之后便可以继续了解ChromeOS对于Android系统的对接逻辑了。

ARC++ 这篇文章中,Chromium 项目的开发者 David Revenman 详细介绍了 ARC++ 的项目实现。

这里是他的演讲资料:《Arc++ Graphics: Rendering, Compositing and Window Management》。

ARC++ 项目中图形系统的整体结构如下图所示:

arcpp_gracphics_overview.png

在 Chrome OS 上,grallocGLES 驱动使用 DRM(Direct Rendering Manager)来渲染。对于合成,HWComposer先处理所有的Android Surface,然后再交由Chrome OS来与Chrome OS的其他界面一起合成。

对于窗口管理,位置变更和尺寸改变由Android完成,而对于最大化,最小化和全屏由 Chrome OS 完成。

Chrome OS中的输入事件由 Ozone 抽象层完成。它使用 GpuMemoryBuffer 对象来保存在Android端使用gralloc 或在Chrome OS端使用DRM分配的DRM缓冲区。

Exosphere是Chrome OS中的一个组件,它允许其他客户端连接到用户界面。它通过验证所请求的操作来保护Chrome OS免受潜在恶意客户端(如Android应用)的侵害。

Android和Chrome OS借助于Wayland协议来完成窗口管理和输入事件的通信。

Chrome OS 中的相关项目见下面这些链接:

ARCVM 项目

虚拟机和容器

在虚拟化技术中,虚拟机和容器是很常见的概念。它们非常相似,但不完全一样。

简单来说,虚拟机是对机器的抽象,而容器是对操作系统的抽象。在实际的运行过程中,每个虚拟机会有独立的操作系统内核。而容器互相之间共享同一个内核。

  • 虚拟机通常更”重“,因为它要占用更多的系统资源。不过好处是每个虚拟机之间隔离得更好,运行在同一个物理机的多个虚拟机,如果其中某一个出现了问题,不会影响其他虚拟机和宿主操作系统。
  • 容器通常更”轻“,因为它不需要独立的内核(大家所熟悉的Docker就是一个容器)。但容器的缺点也正是因为它是共享同一个内核:如果某个容器中的进程触及了内核的某个Bug,导致内核出现问题,这将影响整个系统,当然也包括所有运行在这个系统上的容器。

下图是虚拟机(左)和容器(右)的对比图:

vm_vs_container.gif

Crostini项目

从2018年秋天发布的Chrome OS 69版本开始,用户可以在Chrome OS上面运行Debian Linux,这对于很多技术工作者或者软件开发者来说无疑是极大的方便,有了Linux环境,很多笔记上的工作都可以完成了。

支持这个功能的是Crostini项目。

这个项目的机理是:在Chrome OS的系统上,会运行一个称之为crosvm的虚拟机管理器(类似于QEMU),在这之上来运行Linux虚拟机。

其架构如下图所示:

Crostini_arch.png

这个项目包含了很多的术语,如果你浏览Chrome OS的文档你可能会经常看到这些术语:

  • Cicerone:Chrome OS中的守护进程,用来和容器通信。
  • Concierge:Chrome OS中的守护进程,管理虚拟机和容器的生命周期。
  • crosh:全称是Chrome OS shell,这是Chrome OS上的命令行工具。
  • Crostini:在Chrome OS上提供Linux环境的项目名称。
  • crosvm:Chrome OS上的虚拟机管理器。
  • KVM:全称是Kernel Virtual Machine,这是Linux提供的虚拟机机制。
  • Termina:自定义虚拟机的代码名称。
  • Terminal:获取完整的Linux命令行环境和运行Crostini的公开名称。
  • vsh:虚拟机中的shell。

关于这个项目的更多内容,读者可以阅读下面两个文档:

在这个项目的基础上,出于对系统稳定性和安全性的考虑,Chrome OS的维护者便倾向于将Android的运行环境从容器向虚拟机方向过渡。于是乎有ARCVM(Android Runtime for Chrome OS Virtual Machine)的想法就很自然了。

目前该项目还处于早期的开发阶段,你可以通过Gerrit上的patch了解相关内容:message:arcvm Chromium Gerrit

另外,ARC++和ARCVM项目今后会怎么样,会不会废除前者合并到后者,目前还不确定

获取 Chrome OS 模拟器

对于大部分人来说,可能并没有运行 Chrome OS 的物理设备。不过通过 Android Studio 可以获取 Chrome OS 的模拟器镜像。借此来熟悉 Chrome OS 的环境。

目前(2019年7月) Google 只提供了预览版的镜像。也许很快就会更新,想要获取最新信息,请访问: Android Developers: Apps for Chrome OS overview

在安装好 Android Studio 之后,通过下面的方法可以获取 Chrome OS 的模拟器。

  1. 打开 Android Studio,选择 Tools > SDK Manager
  2. 点击 SDK Update Sites tab。
  3. 点击 + 号,添加 URL 为: https://storage.googleapis.com/chrome_os_emulator/addon2-1.xml,名称随意也可以不填。
  4. 再次点击 + 号,添加 URL 为 https://storage.googleapis.com/chrome_os_emulator/sys-img2-1.xml,名称随意也可以不填。
  5. 点击 Apply
  6. 点击 SDK Tools tab然后在列表中选择 Chrome OS device
  7. 点击 OK 就会安装 Chrome OS 的虚拟设备了。
  8. 重启 Android Studio。
  9. 在Android Studio中,选择 Tools > AVD Manager
  10. 点击 Create Virtual Device 便可以在Tablet分类下面看到 Chrome OS 的虚拟机设备:Pixelbook。如下图所示:
create_chromeos_avd.png

当前的 Chrome OS 系统镜像以Android 7.1.1版本为基础,因此还需要下载相应版本的Android Image才能运行。

下载完成之后启动需要通过Google账号进行登录,如下图所示:

signin_chromeos.png

登录之后可以上拉任务栏可以看见完整的应用列表。从列表中可以看出,系统中内置了Google的GMS。

当然,这也包括了 Google Play 应用商店。

chromeos_launcher.png

Chrome OS 中的进程

Chrome OS 的虚拟设备启动之后,我们可以用熟悉的 adb 命令来了解其环境。

首先通过adb shell 进入的系统中。

在登录Google账号之前,系统只启动了部分进程,如下所示:

novato_cheets:/ $ ps
USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME
root      1     0     8176   2020           0 00000000 S /init
system    2     1     5116   1888           0 00000000 S /system/bin/boot_latch
logd      4     1     11864  3076           0 00000000 S /system/bin/logd
root      5     1     7120   2708           0 00000000 S /system/bin/debuggerd
root      6     1     20060  7964           0 00000000 S /system/bin/vold
root      12    5     6864   412            0 00000000 S debuggerd:signaller
root      19    1     3444   576            0 00000000 S /sbin/healthd
shell     20    1     5064   1872           0 00000000 S /system/bin/bugreportd
system    21    1     6460   2292           0 00000000 S /system/bin/servicemanager
system    22    1     80392  28368          0 00000000 S /system/bin/surfaceflinger
root      23    1     1604804 124292          0 00000000 S zygote
shell     24    1     30528  1260           0 00000000 R /sbin/adbd
shell     279   24    5020   2564  sigsuspend ef676a69 S /system/bin/sh
shell     284   279   6416   2408           0 edd48a69 R ps

一旦登录系统之后,再次通过ps命令便可以看到更多的Andorid进程被启动了。

novato_cheets:/ $ ps
USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME
root      1     0     8184   2036           0 00000000 S /init
logd      4     1     12376  3056           0 00000000 S /system/bin/logd
root      5     1     7120   2680           0 00000000 S /system/bin/debuggerd
root      6     1     24416  8060           0 00000000 S /system/bin/vold
root      12    5     6864   536            0 00000000 S debuggerd:signaller
root      19    1     3444   572            0 00000000 S /sbin/healthd
shell     20    1     5064   1856           0 00000000 S /system/bin/bugreportd
system    21    1     6460   2400           0 00000000 S /system/bin/servicemanager
system    22    1     83508  28660          0 00000000 S /system/bin/surfaceflinger
root      23    1     1606816 121436          0 00000000 S zygote
arc-tracing 87    1     17120  6160           0 00000000 S /system/bin/arctraceservice
system    88    1     19212  6204           0 00000000 S /system/bin/arcbridgeservice
audioserver 89    1     33740  10176          0 00000000 S /system/bin/audioserver
cameraserver 90    1     29256  11952          0 00000000 S /system/bin/cameraserver
drm       91    1     18572  7932           0 00000000 S /system/bin/drmserver
root      92    1     7020   3640           0 00000000 S /system/bin/installd
keystore  93    1     15400  6600           0 00000000 S /system/bin/keystore
mediacodec 94    1     36464  13688          0 00000000 S media.codec
media     95    1     29224  11092          0 00000000 S /system/bin/mediadrmserver
mediaex   96    1     51584  13404          0 00000000 S media.extractor
media     97    1     55480  14684          0 00000000 S /system/bin/mediaserver
root      100   1     25992  5236           0 00000000 S /system/bin/netd
system    101   1     15084  6448           0 00000000 S /system/bin/gatekeeperd
root      104   1     5600   2176           0 00000000 S /system/xbin/perfprofd
system    107   23    1810244 189396          0 00000000 S system_server
root      112   100   6420   2900           0 00000000 S /system/bin/iptables-restore
root      123   100   6432   2916           0 00000000 S /system/bin/ip6tables-restore
shell     228   1     12096  1124           0 00000000 R /sbin/adbd
u0_a16    275   23    1047744 79796          0 00000000 S com.android.systemui
radio     335   23    1045676 94992          0 00000000 S com.android.phone
u0_a40    351   23    1083856 94600          0 00000000 S org.chromium.arc.home
u0_a28    447   23    1023400 65240          0 00000000 S android.ext.services
u0_a47    500   23    1028860 67876          0 00000000 S org.chromium.arc.backup_settings
u0_a26    511   23    1030168 70180          0 00000000 S org.chromium.arc.crash_collector
u0_a49    532   23    1028964 68004          0 00000000 S org.chromium.arc.cast_receiver
u0_a23    545   23    1033920 70136          0 00000000 S org.chromium.arc.gms
u0_a56    553   23    1026796 62364          0 00000000 S org.chromium.arc.ime
u0_a46    566   23    1028868 68484          0 00000000 S org.chromium.arc.tts
system    586   23    1069980 93040          0 00000000 S org.chromium.arc.applauncher
u0_a30    600   23    1030132 78984          0 00000000 S org.chromium.arc.intent_helper
u0_a66    634   23    1025280 68548          0 00000000 S com.android.printspooler
u0_a13    655   23    1035140 85384          0 00000000 S android.process.acore
...

当然了,启动了更多的进程需要消耗更多的内存。在 Chrome OS 完全启动之后,其消耗的内存还是比较大的,你可以通过 free -h 或者 dumpsys meminfo 命令来查看。

novato_cheets:/ $ free -h
		total        used        free      shared     buffers
Mem:             3.8G        2.3G        1.5G        3.1M        302M
-/+ buffers/cache:           2.0G        1.8G
Swap:            5.6G           0        5.6G

借助 Android Studio 和 Android 模拟器还有adb命令,我们几乎可以把 Chrome OS 当成与 Android 系统一样来开发应用。

为Chrome OS开发Android应用

虽说运行Chrome OS的设备可以直接访问Google Play商店下载Andorid应用。但是,毕竟运行Chrome OS的设备(更像笔记本电脑)和手机存在较大的差异,因此如果希望应用在Chrome OS上能获得更好的体验,还需要开发者进行一定的优化。

这些优化主要在下面四个方面:

android_app_for_chrome.png
  • 更大的屏幕:手机设备的屏幕尺寸通常是 4 ~ 7英寸。而运行Chrome OS的设备通常是10 ~ 15英寸。直接将手机的应用界面放大到大屏幕上使用通常体验都不太好,因为控件的留白和字体的大小通常是不合适的。
  • 横屏模式:除了游戏和视屏应用之外,手机上的应用大部分都是竖屏的,而运行Chrome OS的设备通常是类似笔记本电脑的横屏。只支持竖屏将浪费很大的屏幕空间。
  • 窗口控制:Android N开始支持多窗口。多窗口中提供了Freeform模式,这使得用户可以自由调整窗口的大小和位置。在桌面电脑上,这是几乎必备的功能。
  • 外设支持:对于Chrome OS设备来说,除了触摸屏之外,键盘,鼠标和手写笔是很常见的输入设备。对于一些应用来说(例如:绘图应用),这些硬件的支持将极大的提升用户的使用效率。

关于这部分内容不再继续展开,有兴趣的读者可以查看下面几个链接:

参考资料与推荐读物


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK