Commit ec181f5c authored by Tibor Goldschwendt's avatar Tibor Goldschwendt Committed by Commit Bot

Auto-load PAKs of a module

We write the list of PAK files in a module to the module's Java
descriptor and load those PAK files when first accessing the module
via the autogenerated module class. This gets rid of the whitelist in
Module.java. Going forward DFM authors simply have to specify pak_deps
and paks in the module_desc.

APKs do not have proper Java module descriptors. Therefore, we add all
resources of modules that are packaged into the chrome APKs to the APK's
main resources.pak.

Change-Id: Iaa555de0682894397ee40e6a12c3681dfd0542eb
Bug: 986960
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1877139
Commit-Queue: Tibor Goldschwendt <tiborg@chromium.org>
Commit-Queue: Yaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Auto-Submit: Tibor Goldschwendt <tiborg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711732}
parent 6a935bbd
...@@ -1265,11 +1265,15 @@ if (current_toolchain == default_toolchain) { ...@@ -1265,11 +1265,15 @@ if (current_toolchain == default_toolchain) {
# #
# Variables: # Variables:
# is_monochrome: If true, generate Monochrome targets rather than Chrome. # is_monochrome: If true, generate Monochrome targets rather than Chrome.
# is_trichrome: Optionally generate Trichrome targets that use monochrome # is_trichrome: (Optional) Generate Trichrome targets that use monochrome
# library targets but don't include webview resources. # library targets but don't include webview resources.
# is_bundle_module: (Optional) If true, generate targets for base bundle
# module.
template("resource_packaging") { template("resource_packaging") {
_is_monochrome = invoker.is_monochrome _is_monochrome = invoker.is_monochrome
_is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome _is_trichrome = defined(invoker.is_trichrome) && invoker.is_trichrome
_is_bundle_module =
defined(invoker.is_bundle_module) && invoker.is_bundle_module
if (_is_trichrome) { if (_is_trichrome) {
_variant = "trichrome_chrome" _variant = "trichrome_chrome"
...@@ -1278,7 +1282,11 @@ if (current_toolchain == default_toolchain) { ...@@ -1278,7 +1282,11 @@ if (current_toolchain == default_toolchain) {
} else { } else {
_variant = "chrome" _variant = "chrome"
} }
_variant += "_apk" if (_is_bundle_module) {
_variant += "_bundle_module"
} else {
_variant += "_apk"
}
if (enable_resource_whitelist_generation) { if (enable_resource_whitelist_generation) {
if (_is_trichrome || _is_monochrome) { if (_is_trichrome || _is_monochrome) {
...@@ -1397,9 +1405,8 @@ if (current_toolchain == default_toolchain) { ...@@ -1397,9 +1405,8 @@ if (current_toolchain == default_toolchain) {
"//weblayer:resources", "//weblayer:resources",
] ]
} }
if (!dfmify_dev_ui) { if (!dfmify_dev_ui || !_is_bundle_module) {
additional_extra_paks += additional_extra_paks += [ "$root_gen_dir/chrome/dev_ui_resources.pak" ]
[ "$root_gen_dir/chrome/dev_ui_page_resources.pak" ]
deps += [ "//chrome/browser/resources:dev_ui_paks" ] deps += [ "//chrome/browser/resources:dev_ui_paks" ]
} }
...@@ -1454,13 +1461,26 @@ if (current_toolchain == default_toolchain) { ...@@ -1454,13 +1461,26 @@ if (current_toolchain == default_toolchain) {
resource_packaging("chrome_apk_pak_assets") { resource_packaging("chrome_apk_pak_assets") {
is_monochrome = false is_monochrome = false
} }
resource_packaging("chrome_bundle_module_pak_assets") {
is_monochrome = false
is_bundle_module = true
}
resource_packaging("monochrome_apk_pak_assets") { resource_packaging("monochrome_apk_pak_assets") {
is_monochrome = true is_monochrome = true
} }
resource_packaging("monochrome_bundle_module_pak_assets") {
is_monochrome = true
is_bundle_module = true
}
resource_packaging("trichrome_chrome_apk_pak_assets") { resource_packaging("trichrome_chrome_apk_pak_assets") {
is_monochrome = false is_monochrome = false
is_trichrome = true is_trichrome = true
} }
resource_packaging("trichrome_chrome_bundle_module_pak_assets") {
is_monochrome = false
is_trichrome = true
is_bundle_module = true
}
} # current_toolchain == host_toolchain } # current_toolchain == host_toolchain
# Monochrome equivalent of Chrome's APK or bundle library template. # Monochrome equivalent of Chrome's APK or bundle library template.
...@@ -1621,6 +1641,7 @@ static_library("browser_test_support") { ...@@ -1621,6 +1641,7 @@ static_library("browser_test_support") {
# target, intended for Android L and M only. # target, intended for Android L and M only.
template("chrome_public_apk_or_module_tmpl") { template("chrome_public_apk_or_module_tmpl") {
_is_modern = defined(invoker.is_modern) && invoker.is_modern _is_modern = defined(invoker.is_modern) && invoker.is_modern
_is_bundle_module = invoker.target_type == "android_app_bundle_module"
chrome_public_common_apk_or_module_tmpl(target_name) { chrome_public_common_apk_or_module_tmpl(target_name) {
forward_variables_from(invoker, forward_variables_from(invoker,
[ [
...@@ -1632,8 +1653,12 @@ template("chrome_public_apk_or_module_tmpl") { ...@@ -1632,8 +1653,12 @@ template("chrome_public_apk_or_module_tmpl") {
"target_type", "target_type",
"enable_multidex", "enable_multidex",
]) ])
deps = _chrome_public_shared_deps
deps = _chrome_public_shared_deps + [ ":chrome_apk_pak_assets" ] if (_is_bundle_module) {
deps += [ ":chrome_bundle_module_pak_assets" ]
} else {
deps += [ ":chrome_apk_pak_assets" ]
}
if (_is_modern) { if (_is_modern) {
android_manifest = chrome_modern_public_android_manifest android_manifest = chrome_modern_public_android_manifest
......
...@@ -234,16 +234,9 @@ template("chrome_public_common_apk_or_module_tmpl") { ...@@ -234,16 +234,9 @@ template("chrome_public_common_apk_or_module_tmpl") {
if (dfmify_dev_ui && (_target_type == "android_apk" || if (dfmify_dev_ui && (_target_type == "android_apk" ||
_target_type == "instrumentation_test_apk")) { _target_type == "instrumentation_test_apk")) {
# Native resource split moves resources out of resources.pak, but this # Dev UI is a feature in a DFM, and APKs don't use DFMs. To make the code
# is a DFM feature, which APKs don't use. To make the resources split # available for APKs add a dependency on it.
# available for APKs, add dependencies to (1) Java classes, (2) deps += [ "//chrome/android/features/dev_ui:java" ]
# resources of the resource split's DFM (e.g., DevUI DFM). The Java
# classes tells Chrome that the DFM is installed, which then causes the
# included resources to be loaded when needed.
deps += [
"//chrome/android/features/dev_ui:java", # (1) from above.
"//chrome/android/features/dev_ui:pak_assets", # (2) from above.
]
} }
if (!is_java_debug) { if (!is_java_debug) {
...@@ -318,6 +311,8 @@ template("chrome_public_common_apk_or_module_tmpl") { ...@@ -318,6 +311,8 @@ template("chrome_public_common_apk_or_module_tmpl") {
# static library target to provide certain shared library deps, and that # static library target to provide certain shared library deps, and that
# this target should not package webview deps. # this target should not package webview deps.
template("monochrome_public_common_apk_or_module_tmpl") { template("monochrome_public_common_apk_or_module_tmpl") {
_is_bundle_module = defined(invoker.target_type) &&
invoker.target_type == "android_app_bundle_module"
if (defined(invoker.enable_multidex)) { if (defined(invoker.enable_multidex)) {
_enable_multidex = invoker.enable_multidex _enable_multidex = invoker.enable_multidex
} else { } else {
...@@ -440,7 +435,12 @@ template("monochrome_public_common_apk_or_module_tmpl") { ...@@ -440,7 +435,12 @@ template("monochrome_public_common_apk_or_module_tmpl") {
# Android N+ better supports multiple locales (https://crbug.com/780847). # Android N+ better supports multiple locales (https://crbug.com/780847).
support_zh_hk = false support_zh_hk = false
_deps += [ "//chrome/android:${_pak_prefix}_apk_pak_assets" ] if (_is_bundle_module) {
_pak_prefix += "_bundle_module"
} else {
_pak_prefix += "_apk"
}
_deps += [ "//chrome/android:${_pak_prefix}_pak_assets" ]
if (_enable_multidex && invoker.target_type == "android_apk" && if (_enable_multidex && invoker.target_type == "android_apk" &&
!defined(invoker.negative_main_dex_globs)) { !defined(invoker.negative_main_dex_globs)) {
......
...@@ -20,12 +20,3 @@ android_library("java") { ...@@ -20,12 +20,3 @@ android_library("java") {
] ]
java_files = [ "java/src/org/chromium/chrome/features/dev_ui/DevUiImpl.java" ] java_files = [ "java/src/org/chromium/chrome/features/dev_ui/DevUiImpl.java" ]
} }
android_assets("pak_assets") {
renaming_sources = [ "$root_gen_dir/chrome/dev_ui_page_resources.pak" ]
renaming_destinations = [ "dev_ui_resources.pak" ]
deps = [
"//chrome/browser/resources:dev_ui_paks",
]
disable_compression = true
}
...@@ -10,12 +10,8 @@ declare_args() { ...@@ -10,12 +10,8 @@ declare_args() {
dev_ui_module_desc = { dev_ui_module_desc = {
name = "dev_ui" name = "dev_ui"
java_deps = [ "//chrome/android/features/dev_ui:java" ]
# These deps are also used to support non-bundle flows, e.g., APK builds and
# unit tests.
java_deps = [
"//chrome/android/features/dev_ui:java",
"//chrome/android/features/dev_ui:pak_assets",
]
android_manifest = "//chrome/android/features/dev_ui/java/AndroidManifest.xml" android_manifest = "//chrome/android/features/dev_ui/java/AndroidManifest.xml"
paks = [ "$root_gen_dir/chrome/dev_ui_resources.pak" ]
pak_deps = [ "//chrome/browser/resources:dev_ui_paks" ]
} }
...@@ -57,9 +57,20 @@ template("chrome_feature_module") { ...@@ -57,9 +57,20 @@ template("chrome_feature_module") {
not_needed([ "_is_monochrome_or_trichrome" ]) not_needed([ "_is_monochrome_or_trichrome" ])
} }
if (defined(_module_desc.pak_deps)) {
android_assets("${target_name}__pak_assets") {
sources = _module_desc.paks
deps = _module_desc.pak_deps
disable_compression = true
}
}
module_desc_java("${target_name}__module_desc_java") { module_desc_java("${target_name}__module_desc_java") {
module_name = _module_desc.name module_name = _module_desc.name
shared_libraries = _shared_libraries shared_libraries = _shared_libraries
if (defined(_module_desc.pak_deps)) {
paks = _module_desc.paks
}
} }
android_app_bundle_module(target_name) { android_app_bundle_module(target_name) {
...@@ -78,6 +89,9 @@ template("chrome_feature_module") { ...@@ -78,6 +89,9 @@ template("chrome_feature_module") {
deps = [ deps = [
":${target_name}__module_desc_java", ":${target_name}__module_desc_java",
] ]
if (defined(_module_desc.pak_deps)) {
deps += [ ":${target_name}__pak_assets" ]
}
if (defined(_module_desc.java_deps)) { if (defined(_module_desc.java_deps)) {
deps += _module_desc.java_deps deps += _module_desc.java_deps
} }
......
...@@ -33,6 +33,8 @@ if (enable_arcore) { ...@@ -33,6 +33,8 @@ if (enable_arcore) {
# library files going into module if the module is executed in 32 bit. # library files going into module if the module is executed in 32 bit.
# loadable_modules_64_bit: (Optional) List of additional 64-bit shared # loadable_modules_64_bit: (Optional) List of additional 64-bit shared
# library files going into module if the module is executed in 64 bit. # library files going into module if the module is executed in 64 bit.
# pak_deps: (Optional) Grit or repack targets of PAKs going into module.
# paks: (Optional) PAKs going into module.
# Each new module needs to add a desc to one of the lists below. # Each new module needs to add a desc to one of the lists below.
# Modules shipped in Chrome Modern (Android L+). # Modules shipped in Chrome Modern (Android L+).
......
...@@ -56,13 +56,3 @@ generate_jni_registration("jni_registration") { ...@@ -56,13 +56,3 @@ generate_jni_registration("jni_registration") {
header_output = "$target_gen_dir/jni_registration.h" header_output = "$target_gen_dir/jni_registration.h"
namespace = "test_dummy" namespace = "test_dummy"
} }
android_assets("pak_assets") {
sources = [
"$root_gen_dir/chrome/test_dummy_resources.pak",
]
deps = [
"//chrome/android/features/test_dummy/internal:resources_native",
]
disable_compression = true
}
...@@ -11,11 +11,12 @@ test_dummy_module_desc = { ...@@ -11,11 +11,12 @@ test_dummy_module_desc = {
java_deps = [ java_deps = [
"//chrome/android/features/test_dummy/internal:java", "//chrome/android/features/test_dummy/internal:java",
"//chrome/android/modules/test_dummy/internal:java", "//chrome/android/modules/test_dummy/internal:java",
"//chrome/android/modules/test_dummy/internal:pak_assets",
] ]
native_deps = [ native_deps = [
"//chrome/android/features/test_dummy/internal:native", "//chrome/android/features/test_dummy/internal:native",
"//chrome/android/modules/test_dummy/internal:native", "//chrome/android/modules/test_dummy/internal:native",
] ]
paks = [ "$root_gen_dir/chrome/test_dummy_resources.pak" ]
pak_deps =
[ "//chrome/android/features/test_dummy/internal:resources_native" ]
} }
...@@ -363,7 +363,7 @@ if (enable_webui_tab_strip) { ...@@ -363,7 +363,7 @@ if (enable_webui_tab_strip) {
} }
repack("dev_ui_paks") { repack("dev_ui_paks") {
output = "$root_gen_dir/chrome/dev_ui_page_resources.pak" output = "$root_gen_dir/chrome/dev_ui_resources.pak"
sources = [ sources = [
"$root_gen_dir/chrome/bluetooth_internals_resources.pak", "$root_gen_dir/chrome/bluetooth_internals_resources.pak",
......
...@@ -134,7 +134,7 @@ template("chrome_extra_paks") { ...@@ -134,7 +134,7 @@ template("chrome_extra_paks") {
# New paks should be added here by default. # New paks should be added here by default.
sources += [ sources += [
"$root_gen_dir/chrome/component_extension_resources.pak", "$root_gen_dir/chrome/component_extension_resources.pak",
"$root_gen_dir/chrome/dev_ui_page_resources.pak", "$root_gen_dir/chrome/dev_ui_resources.pak",
"$root_gen_dir/chrome/downloads_resources.pak", "$root_gen_dir/chrome/downloads_resources.pak",
"$root_gen_dir/chrome/local_ntp_resources.pak", "$root_gen_dir/chrome/local_ntp_resources.pak",
"$root_gen_dir/chrome/settings_resources.pak", "$root_gen_dir/chrome/settings_resources.pak",
......
...@@ -3668,7 +3668,6 @@ test("unit_tests") { ...@@ -3668,7 +3668,6 @@ test("unit_tests") {
# that DevUI page tests would work. # that DevUI page tests would work.
deps += [ deps += [
"//chrome/android/features/dev_ui:java", "//chrome/android/features/dev_ui:java",
"//chrome/android/features/dev_ui:pak_assets",
"//chrome/android/modules/dev_ui/provider:java", "//chrome/android/modules/dev_ui/provider:java",
] ]
} }
......
...@@ -132,18 +132,11 @@ public class Module<T> { ...@@ -132,18 +132,11 @@ public class Module<T> {
private static void loadNative(String name) { private static void loadNative(String name) {
// Can only initialize native once per lifetime of Chrome. // Can only initialize native once per lifetime of Chrome.
if (sInitializedModules.contains(name)) return; if (sInitializedModules.contains(name)) return;
String[] libraries = loadModuleDescriptor(name).getLibraries(); ModuleDescriptor moduleDescriptor = loadModuleDescriptor(name);
// TODO(crbug.com/986960): Automatically determine if module has native String[] libraries = moduleDescriptor.getLibraries();
// resources instead of whitelisting. String[] paks = moduleDescriptor.getPaks();
boolean loadResources = false; if (libraries.length > 0 || paks.length > 0) {
if ("test_dummy".equals(name)) { ModuleJni.get().loadNative(name, libraries, paks);
loadResources = true;
}
if ("dev_ui".equals(name)) {
loadResources = true;
}
if (libraries.length > 0 || loadResources) {
ModuleJni.get().loadNative(name, libraries, loadResources);
} }
sInitializedModules.add(name); sInitializedModules.add(name);
} }
...@@ -165,6 +158,11 @@ public class Module<T> { ...@@ -165,6 +158,11 @@ public class Module<T> {
public String[] getLibraries() { public String[] getLibraries() {
return new String[0]; return new String[0];
} }
@Override
public String[] getPaks() {
return new String[0];
}
}; };
} }
...@@ -191,6 +189,6 @@ public class Module<T> { ...@@ -191,6 +189,6 @@ public class Module<T> {
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void loadNative(String name, String[] libraries, boolean loadResources); void loadNative(String name, String[] libraries, String[] paks);
} }
} }
...@@ -12,4 +12,8 @@ public interface ModuleDescriptor { ...@@ -12,4 +12,8 @@ public interface ModuleDescriptor {
* Returns the list of native library names this module requires at runtime. * Returns the list of native library names this module requires at runtime.
*/ */
String[] getLibraries(); String[] getLibraries();
/**
* Returns the list of PAK resources files this module contains.
*/
String[] getPaks();
} }
...@@ -74,9 +74,9 @@ void RegisterJni(JNIEnv* env, void* library_handle, const std::string& name) { ...@@ -74,9 +74,9 @@ void RegisterJni(JNIEnv* env, void* library_handle, const std::string& name) {
CHECK(registration_function(env)) << "JNI registration failed: " << name; CHECK(registration_function(env)) << "JNI registration failed: " << name;
} }
void LoadResources(const std::string& name) { void LoadResources(const std::string& pak) {
module_installer::ScopedAllowModulePakLoad scoped_allow_module_pak_load; module_installer::ScopedAllowModulePakLoad scoped_allow_module_pak_load;
ui::LoadPackFileFromApk("assets/" + name + "_resources.pak"); ui::LoadPackFileFromApk("assets/" + pak);
} }
} // namespace } // namespace
...@@ -85,7 +85,7 @@ static void JNI_Module_LoadNative( ...@@ -85,7 +85,7 @@ static void JNI_Module_LoadNative(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jstring>& jname, const base::android::JavaParamRef<jstring>& jname,
const base::android::JavaParamRef<jobjectArray>& jlibraries, const base::android::JavaParamRef<jobjectArray>& jlibraries,
jboolean load_resources) { const base::android::JavaParamRef<jobjectArray>& jpaks) {
std::string name; std::string name;
base::android::ConvertJavaStringToUTF8(env, jname, &name); base::android::ConvertJavaStringToUTF8(env, jname, &name);
std::vector<std::string> libraries; std::vector<std::string> libraries;
...@@ -101,8 +101,10 @@ static void JNI_Module_LoadNative( ...@@ -101,8 +101,10 @@ static void JNI_Module_LoadNative(
// function. // function.
RegisterJni(env, library_handle, name); RegisterJni(env, library_handle, name);
} }
if (load_resources) { std::vector<std::string> paks;
LoadResources(name); base::android::AppendJavaStringArrayToStringVector(env, jpaks, &paks);
for (const auto& pak : paks) {
LoadResources(pak);
} }
} }
......
...@@ -17,6 +17,7 @@ import("//build/config/python.gni") ...@@ -17,6 +17,7 @@ import("//build/config/python.gni")
# shared_libraries: (Optional) List of shared_library targets the module # shared_libraries: (Optional) List of shared_library targets the module
# requires at runtime. Will consider all transitively depended on # requires at runtime. Will consider all transitively depended on
# shared_libraries. # shared_libraries.
# paks: (Optional) PAK files going into the module.
template("module_desc_java") { template("module_desc_java") {
_target_name = target_name _target_name = target_name
...@@ -55,6 +56,13 @@ template("module_desc_java") { ...@@ -55,6 +56,13 @@ template("module_desc_java") {
"--output", "--output",
rebase_path(_srcjar, root_out_dir), rebase_path(_srcjar, root_out_dir),
] ]
if (defined(invoker.paks)) {
_rebased_paks = []
foreach(_pak, invoker.paks) {
_rebased_paks += [ rebase_path(_pak, root_out_dir) ]
}
args += [ "--paks=$_rebased_paks" ]
}
} }
android_library(_target_name) { android_library(_target_name) {
......
...@@ -27,11 +27,17 @@ import org.chromium.base.annotations.UsedByReflection; ...@@ -27,11 +27,17 @@ import org.chromium.base.annotations.UsedByReflection;
@UsedByReflection("Module.java") @UsedByReflection("Module.java")
public class ModuleDescriptor_{MODULE} implements ModuleDescriptor {{ public class ModuleDescriptor_{MODULE} implements ModuleDescriptor {{
private static final String[] LIBRARIES = {{{LIBRARIES}}}; private static final String[] LIBRARIES = {{{LIBRARIES}}};
private static final String[] PAKS = {{{PAKS}}};
@Override @Override
public String[] getLibraries() {{ public String[] getLibraries() {{
return LIBRARIES; return LIBRARIES;
}} }}
@Override
public String[] getPaks() {{
return PAKS;
}}
}} }}
""" """
...@@ -41,10 +47,12 @@ def main(): ...@@ -41,10 +47,12 @@ def main():
parser.add_argument('--module', required=True, help='The module name.') parser.add_argument('--module', required=True, help='The module name.')
parser.add_argument( parser.add_argument(
'--libraries', required=True, help='GN list of native library paths.') '--libraries', required=True, help='GN list of native library paths.')
parser.add_argument('--paks', help='GN list of PAK file paths')
parser.add_argument( parser.add_argument(
'--output', required=True, help='Path to the generated srcjar file.') '--output', required=True, help='Path to the generated srcjar file.')
options = parser.parse_args(build_utils.ExpandFileArgs(sys.argv[1:])) options = parser.parse_args(build_utils.ExpandFileArgs(sys.argv[1:]))
options.libraries = build_utils.ParseGnList(options.libraries) options.libraries = build_utils.ParseGnList(options.libraries)
options.paks = build_utils.ParseGnList(options.paks)
libraries = [] libraries = []
for path in options.libraries: for path in options.libraries:
...@@ -54,10 +62,12 @@ def main(): ...@@ -54,10 +62,12 @@ def main():
assert filename.endswith('.so') assert filename.endswith('.so')
# Remove lib prefix and .so suffix. # Remove lib prefix and .so suffix.
libraries += [filename[3:-3]] libraries += [filename[3:-3]]
paks = options.paks if options.paks else []
format_dict = { format_dict = {
'MODULE': options.module, 'MODULE': options.module,
'LIBRARIES': ','.join(['"%s"' % l for l in libraries]), 'LIBRARIES': ','.join(['"%s"' % l for l in libraries]),
'PAKS': ','.join(['"%s"' % os.path.basename(p) for p in paks]),
} }
with build_utils.AtomicOutput(options.output) as f: with build_utils.AtomicOutput(options.output) as f:
with zipfile.ZipFile(f.name, 'w') as srcjar_file: with zipfile.ZipFile(f.name, 'w') as srcjar_file:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment