前言
最近某个项目需要轻度定制的 Chromium ,记录一下编译和修改的过程。
这篇文章主要记录以下内容:
- 如何拉取 Chromium for android 的代码
- 如何编译 Chromium for android
- 一些对 Chromium for android 的小定制与修改
- 看 Chromium 源码时的经验小记
谷歌官方的编译方式可以在这里找到:
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/android_build_instructions.md
本文会在官方说明的基础上进行进一步的解释与补充。
工作环境
编译 Chromium for android 需要 Linux 环境,并且只能使用 Linux 环境。
本文所使用的编译环境时 Arch Linux。
编译机配置,推荐 16GB 内存(跑的时候峰值需求能到 9GB 多),100GB 磁盘空间(拉取完整源码并编译 98 版本,最后实际消耗 78GB )。
首先的首先,创建一个文件夹,用来存放相关内容。mkdir ~/work
cd ~/work
编译需要一些软件包的支持,由于此处的编译环境是 Arch Linux ,官方并没有为其提供一键安装软件包的脚本,因此基本上是报错缺啥装啥。
当然, base-devel
可以先装好。
源码的拉取
源码本体就在这里。
https://chromium.googlesource.com/chromium/src/
但是,由于编译源码需要一些额外的树外工具和 hooks ,而这些东西并不包含在主代码中,因此我们仍然需要使用谷歌的官方工具进行源码拉取。
获取源码管理工具
下载工具。git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
将工具增加到环境变量。export PATH="${PATH}:${HOME}/work/depot_tools"
拉取源码
mkdir chromium && cd chromium
fetch --nohooks android
此处拉取的完整代码,为的是稍后切换版本时方便,我想没有人会想把非常不稳定的主线版本拿来日用吧。--nohooks
代表暂时先不安装 hooks ,而只是拉取代码,hooks 我们稍后安装,按部就班的来。
这一步可能需要非常久的时间,而且建议开启代理,源码大小在 50GB 左右。
选择版本
在上一步完成后,工作目录下会多出一个 src
文件夹。
进入此文件夹。cd src
从仓库刷新所有的 Tags。git fetch origin --tags
查看 Tags。git tag
选择一个心仪的 Tag 检出代码,比如:git checkout 97.0.4692.93
安装 hooks 和 树外依赖
(ubuntu专用)安装依赖软件包./build/install-build-deps-android.sh
Arch Linux 并不支持这个脚本,因此需要手动的“缺啥补啥”。
某些软件包甚至 Arch 官方仓库里没有,需要从 AUR 安装,比如ncurses5-compat-libs
再次刷新源码并安装 树外依赖 和 hooks 。gclient sync
这一步也需要下载不少的东西,请确保网络畅通。
编译
配置编译
指定编译配置文件。gn args out/Default
其中,out/Default
是编译输出目录。
这一步操作后会打开一个文本编辑器,在其中写入编译配置:
# 目标操作系统
target_os = "android"
# 目标架构
target_cpu = "arm64"
# 不把警告作为错误,否则有一定可能性遭遇警告转来的编译错误
treat_warnings_as_errors = false
# 编译“正式版”,而非“开发人员内部版本”,启动正式版具有的性能优化
is_official_build = true
# 编译 ffmpeg 相关模块以提供 H.264 视频解码功能
ffmpeg_branding = "Chrome"
proprietary_codecs = true
开始编译
autoninja -C out/Default chrome_public_apk
然后编译就开始了,记得依赖缺啥补啥。
编译完成后,可以在 out/Default/apks
下找到安装包。
刷新代码
也许有一天,你会想要更新本地代码,拉取新代码编译新版 Chromium,此时需要做的是:
- 配置环境变量
- 进入
src
文件夹 - 获取新代码:
git fetch origin --tags
- 检出新代码:
git checkout <新的版本>
- 更新 Hooks 和 树外工具:
gclient sync
- 编译!
autoninja -C out/Default chrome_public_apk
搞定!
魔改
干掉 StrictMode
自编译 Chromium 在打开时会在屏幕边缘短暂绘制一个红框,在主线程执行长时间操作时也会绘制,可以通过干掉 StrictMode 解决。
diff --git a/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java b/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java
index 1c9e868c8fdab..2fc3cebba6f2f 100644
--- a/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java
+++ b/components/strictmode/android/java/src/org/chromium/components/strictmode/ReflectiveThreadStrictModeInterceptor.java
@@ -68,7 +68,7 @@ final class ReflectiveThreadStrictModeInterceptor implements ThreadStrictModeInt
// trace with stack frames prior to android.os.Handler calls stripped out.
interceptWithReflection();
- StrictMode.setThreadPolicy(new ThreadPolicy.Builder(detectors).penaltyLog().build());
+ //StrictMode.setThreadPolicy(new ThreadPolicy.Builder(detectors).penaltyLog().build());
}
private void interceptWithReflection() {
修改默认搜索引擎
diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc
index c9c393401e513..33a502ed3e06f 100644
--- a/components/search_engines/template_url_prepopulate_data.cc
+++ b/components/search_engines/template_url_prepopulate_data.cc
@@ -201,10 +201,9 @@ const PrepopulatedEngine* const engines_CL[] = {
// China
const PrepopulatedEngine* const engines_CN[] = {
- &sogou,
- &baidu,
&bing,
- &google,
+ &baidu,
+ &sogou,
&so_360,
};
注意:只要搜索引擎列表里有谷歌,默认搜索引擎永远是谷歌,把谷歌删了后,默认搜索引擎是第一个。
默认关闭登录谷歌引导
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc
index 51ca2abc2b158..160c45365126a 100644
--- a/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -55,7 +55,7 @@ void PrimaryAccountManager::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(prefs::kGoogleServicesConsentedToSync, false);
registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
- registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
+ registry->RegisterBooleanPref(prefs::kSigninAllowed, false);
registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
}
Chromium 中的默认偏好都是在 Native 层中使用如上方式注册的,因此在搜索某个设置时可以使用:grep -rn "Register.*Pref" --exclude-dir=out --exclude-dir=.git | grep -i <你的关键词>
来快速定位一个设置。
移除不想要的启动引导页面
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 78c793c0e7c46..2f0d6da51dd21 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -139,7 +139,7 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
private void createFirstPage() {
FREMobileIdentityConsistencyFieldTrial.createFirstRunTrial();
BooleanSupplier showWelcomePage = () -> !FirstRunStatus.shouldSkipWelcomePage();
- if (FREMobileIdentityConsistencyFieldTrial.isEnabled()) {
+ if (false) {
mPages.add(new FirstRunPage<>(SigninFirstRunFragment.class, showWelcomePage));
} else {
// TODO(crbug.com/1111490): Revisit during post-MVP.
@@ -178,44 +178,6 @@ public class FirstRunActivity extends FirstRunActivityBase implements FirstRunPa
assert areNativeAndPoliciesInitialized();
mFirstRunFlowSequencer.updateFirstRunProperties(mFreProperties);
- BooleanSupplier showDataReductionPromo =
- () -> mFreProperties.getBoolean(SHOW_DATA_REDUCTION_PAGE);
- BooleanSupplier showSearchEnginePromo =
- () -> mFreProperties.getBoolean(SHOW_SEARCH_ENGINE_PAGE);
- BooleanSupplier showSyncConsent = () -> mFreProperties.getBoolean(SHOW_SYNC_CONSENT_PAGE);
-
- // An optional Data Saver page.
- if (!FREMobileIdentityConsistencyFieldTrial.isEnabled()
- && showDataReductionPromo.getAsBoolean()) {
- mPages.add(new FirstRunPage<>(
- DDAjrXkGz1p2FHQMfZ6QaedHZbxtzt1TCb.class, showDataReductionPromo));
- mFreProgressStates.add(MobileFreProgress.DATA_SAVER_SHOWN);
- }
-
- // An optional page to select a default search engine.
- if (showSearchEnginePromo.getAsBoolean()) {
- mPages.add(new FirstRunPage<>(
- DefaultSearchEngineFirstRunFragment.class, showSearchEnginePromo));
- mFreProgressStates.add(MobileFreProgress.DEFAULT_SEARCH_ENGINE_SHOWN);
- }
-
- // An optional sync consent page, the visibility of this page will be decided on the fly
- // according to the situation.
- mPages.add(new FirstRunPage<>(SyncConsentFirstRunFragment.class, showSyncConsent));
- mFreProgressStates.add(MobileFreProgress.SYNC_CONSENT_SHOWN);
-
- // An optional Data Saver page, this page will be hidden if users click the |Settings|
- // link on the sync consent page.
- if (FREMobileIdentityConsistencyFieldTrial.isEnabled()
- && showDataReductionPromo.getAsBoolean()) {
- mPages.add(new FirstRunPage<>(
- DDAjrXkGz1p2FHQMfZ6QaedHZbxtzt1TCb.class, showDataReductionPromo));
- mFreProgressStates.add(MobileFreProgress.DATA_SAVER_SHOWN);
- }
-
- if (mPagerAdapter != null) {
- mPagerAdapter.notifyDataSetChanged();
- }
mPostNativeAndPolicyPagesCreated = true;
if (sObserver != null) {
这里把所有可选的引导页面都删完了,只留了个欢迎屏幕,同时也禁用了欢迎屏幕在 GMS 可用时显示登录选项的功能。
移除不想要的设置选项
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
index 39f3c5c3aa135..b465a174147e5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -255,9 +255,9 @@ public class MainSettings extends PreferenceFragmentCompat
removePreferenceIfPresent(PREF_DEVELOPER);
}
- ChromeBasePreference dataReduction =
- (ChromeBasePreference) findPreference(PREF_DATA_REDUCTION);
- dataReduction.setSummary(DataReductionPreferenceFragment.generateSummary(getResources()));
+ removePreferenceIfPresent(PREF_ACCOUNT_AND_GOOGLE_SERVICES_SECTION);
+ removePreferenceIfPresent(PREF_GOOGLE_SERVICES);
+ removePreferenceIfPresent(PREF_DATA_REDUCTION);
}
不显示开发者选项
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
index 1f9156c7fb11d..9608cdfecfec0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/settings/DeveloperSettings.java
@@ -33,7 +33,6 @@ public class DeveloperSettings extends PreferenceFragmentCompat {
// Chrome version in Settings>About multiple times.
if (sIsEnabledForTests != null) return sIsEnabledForTests;
- if (VersionConstants.CHANNEL <= Channel.DEV) return true;
return SharedPreferencesManager.getInstance().readBoolean(
ChromePreferenceKeys.SETTINGS_DEVELOPER_ENABLED, false);
}
禁用主页上的“探索”
diff --git a/components/feed/core/shared_prefs/pref_names.cc b/components/feed/core/shared_prefs/pref_names.cc
index 57a65895fbded..511f7a2b500e1 100644
--- a/components/feed/core/shared_prefs/pref_names.cc
+++ b/components/feed/core/shared_prefs/pref_names.cc
@@ -20,8 +20,8 @@ const char kArticlesListVisible[] = "ntp_snippets.list_visible";
const char kVideoPreviewsType[] = "ntp_snippets.video_previews_type";
void RegisterFeedSharedProfilePrefs(PrefRegistrySimple* registry) {
- registry->RegisterBooleanPref(kEnableSnippets, true);
- registry->RegisterBooleanPref(kArticlesListVisible, true);
+ registry->RegisterBooleanPref(kEnableSnippets, false);
+ registry->RegisterBooleanPref(kArticlesListVisible, false);
registry->RegisterIntegerPref(kVideoPreviewsType, 1);
}