后AOSP时代还能贡献代码吗?

一个月前,Android闭源的消息铺天盖地。后来大家弄清楚了,Google只是将Android的开发全都切为内部分支,而代码依旧开源(虽然会滞后)。因此,如果我们现在登录AOSP的网页,将会看到这样的置顶信息:

今天我们就来试一试,在后AOSP时代,还能不能贡献代码?以及该如何贡献代码?

起源

(本章节涉及技术细节,如果不感兴趣可以跳过)

事情的起源是我们内部测试碰到一个非常诡异的问题:一些核心系统进程消失了,init认为它启动成功了,可是进程列表中根本找不到。通过分析dump和加日志的方式,我们找到了问题的根因:Android 15中引入了一个功能,在传统cgroup的树状结构中增加apps和system两个根节点,这样我们对系统进程和普通应用可以执行不同的策略。

因此传统的cgroup目录结构就发生了如下变化:

bash 复制代码
/sys/fs/cgroup/uid_10118/pid_4980
               ↓↓↓
/sys/fs/cgroup/apps/uid_10228/pid_5621
/sys/fs/cgroup/system/uid_1000/pid_1348

虽然这个功能在Android 15中就已引入,但直到Android 16才默认开启。

正常情况下,当App死亡后,system_server会收到通知,然后它会负责清理该App对应的cgroup节点。但如果是系统重启(zygote死亡),system_server是来不及为众多App回收cgroup节点的。因此init在回收zygote时,会执行一个removeAllEmptyProcessGroups的操作,将cgroup系统中那些空节点删除,相当于干了本该system_server干的活。

整个流程没有缺陷,但新引入的功能却忽略了removeAllEmptyProcessGroupsremoveAllEmptyProcessGroups依然按照老的cgroup目录结构进行处理,结果就是那些空节点无法删除,会被fork出的新进程继承使用。一旦这些节点的freeze状态为true,就会使得新进程被冻结。这个影响无疑是灾难性的。

后续

弄清楚事情的原委后,便可以着手准备fix patch。

首先是下载源码,我们需要更改的文件是/system/core/libprocessgroup/processgroup.cpp,它属于的仓库是platform/system/core。这里简单介绍下Android源码的结构,它由上百个不同的Git仓库组成,譬如常见的platform/frameworks/base和platform/art。而最后组合这些Git仓库的地方就叫做manifest,它里面指定了每个仓库需要用到的版本。至于常用的工具repo,它底层调用的就是git命令,只不过它可以基于manifest帮我们便捷管理成百上千个Git仓库。

通过这个网页,我们可以获取platform/system/core这个仓库的下载地址,以及生成Change-Id的Hook:

bash 复制代码
git clone https://android.googlesource.com/platform/system/core && (cd core && f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f)

下载完代码后,默认的分支为main。这个分支已经停止更新,因此我们需要按照AOSP的要求切换到android-latest-release。但其实android-latest-release并不是一个仓库分支,而是mainfest的分支。我们可以根据它来找到具体仓库的版本。

根据上图的内容,我们可以知道当下每个具体Git仓库的版本为android15-qpr2-release。这里的qpr指的是"Quarterly Platform Release",qpr2表示Android 15的第二次季度更新。因此我们可以采用如下命令切换到android15-qpr2-release分支。

arduino 复制代码
git checkout -b android15-qpr2-release origin/android15-qpr2-release

之后是代码改动,提交。Commit message里需要填入Google Issue Tracker的Bug ID,因此我们需要提前创建好Ticket,在里面描述清楚问题,以及和Google做必要的沟通。提交后的代码需要push到远程仓库,采用如下命令:

ruby 复制代码
git push --no-thin origin HEAD:refs/for/android15-qpr2-release

提交完之后,系统会返回一个android-review的链接给你。拿着它,我们便可以看到具体的提交。

Google的工程师结合Google Issue上的描述和这里的提交便可以对代码进行review。通过review comment,我们可以不断更新patchset,让修复尽可能完美。

最后,Google的工程师会将我们的代码cherrypick进他们的内部版本,这样我们便可以在日后的开源版本中看见自己的改动。而android-review上的这笔改动会被abandoned,表明这笔改动已被处理。

那我们如何知道自己的改动是被接纳了还是拒绝了呢?其实大多数Google的工程师都会友好地在Google Issue上回复状态,就像下面这样。

感受

虽然后AOSP时代依然可以贡献代码,但感觉远没有以前"友好",具体原因如下:

  1. android-latest-release是已经成熟的Android源码,而Google内部版本可能已经领先大半年了。这样一来,我们基于老版本不管是提交bug fix还是feature,Google的内部版本可能都已经有了。因此提交很可能变成无用功。
  2. 由于版本差异过大,Google cherrypick时大概率需要解冲突,这既增加了他们的人力开支,也让他们更倾向于自己改动,而非cherrypick。
  3. Google内部版本合入时碰到的错误我们看不到,黑盒般的来回沟通会费力费神。

事物的发展大抵如此,曾经开放的走向封闭,曾经繁华的走向萧条。不过,我们也不必为这种变化感到伤怀,就像千年前刘禹锡曾告诉我们的那样:沉舟侧畔千帆过,病树前头万木春。

相关推荐
桦说编程2 小时前
深入解析CompletableFuture源码实现
java·性能优化·源码
还鮟4 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡5 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi005 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil7 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你7 小时前
Android View的绘制原理详解
android
移动开发者1号10 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号10 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best15 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk15 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk