Commit cc47e0cd authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

Implement application loading with isolatedSplits="true"

This change adds new application classes for Chrome/Monochrome which can
be used with isolated splits to load the logic from the real application
classes from the chrome split in the browser process. In child
processes, only the necessary initialization will be done, and the
chrome split will never be loaded.

Application methods which have logic in ChromeApplication or
MonochromeApplication have been moved an inner implementation class,
which will then be called from the SplitCompatApplication superclass.

Fonts were moved to the base module because they were conflicting with
resources from the elements aar.

Unfortunately, there is an Android bug with how services are loaded from
isolated splits (b/169196314). I'll fix this in a follow up.

Bug: 1126301
Change-Id: Icafe93a8c6fb560315c3022839544faaa0327fcc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425404
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811930}
parent 52c6e53c
...@@ -161,8 +161,13 @@ generate_ui_locale_resources("ui_locale_string_resources") { ...@@ -161,8 +161,13 @@ generate_ui_locale_resources("ui_locale_string_resources") {
# if the enable_chrome_module gn arg is true. # if the enable_chrome_module gn arg is true.
android_resources("chrome_base_module_resources") { android_resources("chrome_base_module_resources") {
sources = [ sources = [
"java/res_base/anim/no_anim.xml",
"java/res_base/font/google_sans.xml",
"java/res_base/font/google_sans_bold.xml",
"java/res_base/font/google_sans_medium.xml",
"java/res_base/values/ic_launcher_alias.xml", "java/res_base/values/ic_launcher_alias.xml",
"java/res_base/values/ic_launcher_round_alias.xml", "java/res_base/values/ic_launcher_round_alias.xml",
"java/res_base/values/preloaded_fonts.xml",
"java/res_base/values/values.xml", "java/res_base/values/values.xml",
"java/res_base/xml/network_security_config.xml", "java/res_base/xml/network_security_config.xml",
"java/res_chromium_base/mipmap-hdpi/app_icon.png", "java/res_chromium_base/mipmap-hdpi/app_icon.png",
...@@ -272,10 +277,10 @@ java_cpp_template("vr_build_config") { ...@@ -272,10 +277,10 @@ java_cpp_template("vr_build_config") {
android_library("chrome_java") { android_library("chrome_java") {
deps = [ deps = [
":base_module_java",
":chrome_app_java_resources", ":chrome_app_java_resources",
":chrome_public_android_manifest", ":chrome_public_android_manifest",
":chrome_public_apk_template_resources", ":chrome_public_apk_template_resources",
":chrome_version_constants",
":partner_location_descriptor_proto_java", ":partner_location_descriptor_proto_java",
":update_proto_java", ":update_proto_java",
":usage_stats_proto_java", ":usage_stats_proto_java",
...@@ -526,7 +531,6 @@ android_library("chrome_java") { ...@@ -526,7 +531,6 @@ android_library("chrome_java") {
srcjar_deps = [ srcjar_deps = [
":chrome_android_java_enums_srcjar", ":chrome_android_java_enums_srcjar",
":chrome_android_java_google_api_keys_srcjar", ":chrome_android_java_google_api_keys_srcjar",
":chrome_product_config",
":chrome_strict_mode_switch", ":chrome_strict_mode_switch",
":resource_id_javagen", ":resource_id_javagen",
":sync_user_settings_enums_java", ":sync_user_settings_enums_java",
...@@ -557,10 +561,7 @@ android_library("chrome_java") { ...@@ -557,10 +561,7 @@ android_library("chrome_java") {
] ]
# From java_sources.gni. # From java_sources.gni.
sources = chrome_java_sources + [ sources = chrome_java_sources + [ app_hooks_impl ]
app_hooks_impl,
_chrome_version_java_file,
]
# Include sources from feed_java_sources.gni. # Include sources from feed_java_sources.gni.
sources += feed_java_sources sources += feed_java_sources
...@@ -579,10 +580,7 @@ android_library("chrome_java") { ...@@ -579,10 +580,7 @@ android_library("chrome_java") {
# Add the actual implementation where necessary so that downstream targets # Add the actual implementation where necessary so that downstream targets
# can provide their own implementations. # can provide their own implementations.
jar_excluded_patterns = [ jar_excluded_patterns = [ "*/AppHooksImpl.class" ]
"*/AppHooksImpl.class",
"*/ProductConfig.class",
]
annotation_processor_deps = [ annotation_processor_deps = [
"//base/android/jni_generator:jni_processor", "//base/android/jni_generator:jni_processor",
...@@ -2039,6 +2037,8 @@ chrome_public_apk_or_module_tmpl("chrome_modern_public_base_bundle_module") { ...@@ -2039,6 +2037,8 @@ chrome_public_apk_or_module_tmpl("chrome_modern_public_base_bundle_module") {
android_library("monochrome_java") { android_library("monochrome_java") {
deps = [ deps = [
":base_module_java",
":base_monochrome_module_java",
"//android_webview:android_webview_java", "//android_webview:android_webview_java",
"//base:base_java", "//base:base_java",
"//chrome/android:chrome_java", "//chrome/android:chrome_java",
...@@ -2048,6 +2048,50 @@ android_library("monochrome_java") { ...@@ -2048,6 +2048,50 @@ android_library("monochrome_java") {
[ "java/src/org/chromium/chrome/browser/MonochromeApplication.java" ] [ "java/src/org/chromium/chrome/browser/MonochromeApplication.java" ]
} }
# Monochrome equivalent of :base_module_java.
android_library("base_monochrome_module_java") {
sources = [
"java/src/org/chromium/chrome/browser/base/SplitMonochromeApplication.java",
]
deps = [
":base_module_java",
"//android_webview:android_webview_java",
"//base:base_java",
"//components/version_info/android:version_constants_java",
]
}
# Target for classes which should be in the base module, even when
# enable_chrome_module is true and //chrome code is in a DFM.
android_library("base_module_java") {
sources = [
"java/src/org/chromium/chrome/browser/base/SplitChromeApplication.java",
"java/src/org/chromium/chrome/browser/base/SplitCompatApplication.java",
_chrome_version_java_file,
]
deps = [
":chrome_base_module_resources",
":chrome_version_constants",
"//base:base_java",
"//components/embedder_support/android:application_java",
"//components/module_installer/android:module_installer_java",
"//components/version_info/android:version_constants_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//ui/android:ui_no_recycler_view_java",
# Deps needed for child processes.
"//components/viz/service:service_java",
"//content/public/android:content_java",
]
srcjar_deps = [ ":chrome_product_config" ]
# Add the actual implementation where necessary so that downstream targets
# can provide their own implementations.
jar_excluded_patterns = [ "*/ProductConfig.class" ]
resources_package = "org.chromium.chrome.base"
}
# Defines a target that derives from the monochrome public application. This # Defines a target that derives from the monochrome public application. This
# can be either an APK or an app bundle module. Note that these only work # can be either an APK or an app bundle module. Note that these only work
# on Android N+ devices, see chrome_public_apk_or_module_tmpl() for a template # on Android N+ devices, see chrome_public_apk_or_module_tmpl() for a template
......
...@@ -13,7 +13,6 @@ chrome_java_resources = [ ...@@ -13,7 +13,6 @@ chrome_java_resources = [
"java/res/anim/activity_open_enter.xml", "java/res/anim/activity_open_enter.xml",
"java/res/anim/decelerate_quart.xml", "java/res/anim/decelerate_quart.xml",
"java/res/anim/fast_out_slow_in_interpolator.xml", "java/res/anim/fast_out_slow_in_interpolator.xml",
"java/res/anim/no_anim.xml",
"java/res/anim/slide_in_up.xml", "java/res/anim/slide_in_up.xml",
"java/res/anim/slide_out_down.xml", "java/res/anim/slide_out_down.xml",
"java/res/anim/stay_hidden.xml", "java/res/anim/stay_hidden.xml",
...@@ -768,9 +767,6 @@ chrome_java_resources = [ ...@@ -768,9 +767,6 @@ chrome_java_resources = [
"java/res/drawable/toolbar_shadow.xml", "java/res/drawable/toolbar_shadow.xml",
"java/res/drawable/trending_up_black_24dp.xml", "java/res/drawable/trending_up_black_24dp.xml",
"java/res/drawable/visa_card.xml", "java/res/drawable/visa_card.xml",
"java/res/font/google_sans.xml",
"java/res/font/google_sans_bold.xml",
"java/res/font/google_sans_medium.xml",
"java/res/layout-sw360dp/preference_spinner_single_line.xml", "java/res/layout-sw360dp/preference_spinner_single_line.xml",
"java/res/layout-sw600dp/find_toolbar.xml", "java/res/layout-sw600dp/find_toolbar.xml",
"java/res/layout-sw600dp/location_bar.xml", "java/res/layout-sw600dp/location_bar.xml",
...@@ -1042,7 +1038,6 @@ chrome_java_resources = [ ...@@ -1042,7 +1038,6 @@ chrome_java_resources = [
"java/res/values/dimens.xml", "java/res/values/dimens.xml",
"java/res/values/drawables.xml", "java/res/values/drawables.xml",
"java/res/values/ids.xml", "java/res/values/ids.xml",
"java/res/values/preloaded_fonts.xml",
"java/res/values/strings.xml", "java/res/values/strings.xml",
"java/res/values/styles.xml", "java/res/values/styles.xml",
"java/res/values/values.xml", "java/res/values/values.xml",
......
...@@ -534,10 +534,12 @@ template("monochrome_public_common_apk_or_module_tmpl") { ...@@ -534,10 +534,12 @@ template("monochrome_public_common_apk_or_module_tmpl") {
# Add all loadable modules and shared libraries from DFMs. # Add all loadable modules and shared libraries from DFMs.
if (_enable_chrome_module) { if (_enable_chrome_module) {
if (!defined(data_deps)) { if (is_monochrome) {
data_deps = [] deps += [ "//chrome/android:base_monochrome_module_java" ]
} else {
deps += [ "//chrome/android:base_module_java" ]
} }
data_deps += _chrome_module_shared_lib_deps deps += _chrome_module_shared_lib_deps
_loadable_modules_32_bit = [] _loadable_modules_32_bit = []
_loadable_modules_64_bit = [] _loadable_modules_64_bit = []
foreach(_module_desc, _module_descs) { foreach(_module_desc, _module_descs) {
...@@ -809,7 +811,7 @@ template("monochrome_public_common_apk_or_module_tmpl") { ...@@ -809,7 +811,7 @@ template("monochrome_public_common_apk_or_module_tmpl") {
# definitions_in_split is true. # definitions_in_split is true.
# split_output: Output path for |split_input|. # split_output: Output path for |split_input|.
# variables: Variables to pass to the jinja templates. # variables: Variables to pass to the jinja templates.
# definitions_in_split: If true will pass skip_definitions=true in the # definitions_in_split: If true will pass definitions_in_split=true in the
# variables passed to |input| and generate |split_output|. # variables passed to |input| and generate |split_output|.
template("split_manifest_template") { template("split_manifest_template") {
_definitions_in_split = _definitions_in_split =
...@@ -823,7 +825,7 @@ template("split_manifest_template") { ...@@ -823,7 +825,7 @@ template("split_manifest_template") {
"variables", "variables",
]) ])
if (_definitions_in_split) { if (_definitions_in_split) {
variables += [ "skip_definitions=true" ] variables += [ "definitions_in_split=true" ]
} }
} }
......
...@@ -13,6 +13,10 @@ by a child template that "extends" this file. ...@@ -13,6 +13,10 @@ by a child template that "extends" this file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="{{ manifest_package }}" package="{{ manifest_package }}"
{% set definitions_in_split = definitions_in_split|default(0) == 'true' %}
{% if definitions_in_split %}
android:isolatedSplits="true"
{% endif %}
tools:ignore="MissingVersion"> tools:ignore="MissingVersion">
<!-- android:versionCode and android:versionName is set through gyp. See build/common.gypi --> <!-- android:versionCode and android:versionName is set through gyp. See build/common.gypi -->
...@@ -147,7 +151,13 @@ by a child template that "extends" this file. ...@@ -147,7 +151,13 @@ by a child template that "extends" this file.
<!-- Set android:largeHeap to "true" to allow more than the default <!-- Set android:largeHeap to "true" to allow more than the default
Java heap limit (32Mb on Nexus S, 48Mb on Xoom). --> Java heap limit (32Mb on Nexus S, 48Mb on Xoom). -->
<application android:name="{% block application_name %}org.chromium.chrome.browser.ChromeApplication{% endblock %}" <application android:name="{% block application_name %}
{%- if definitions_in_split -%}
org.chromium.chrome.browser.base.SplitChromeApplication
{%- else -%}
org.chromium.chrome.browser.ChromeApplication
{%- endif -%}
{% endblock %}"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:roundIcon="@drawable/ic_launcher_round" android:roundIcon="@drawable/ic_launcher_round"
android:label="{% block application_label %}@string/app_name{% endblock %}" android:label="{% block application_label %}@string/app_name{% endblock %}"
...@@ -207,10 +217,6 @@ by a child template that "extends" this file. ...@@ -207,10 +217,6 @@ by a child template that "extends" this file.
"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="org.chromium.components.media_router.caf.CastOptionsProvider"/> android:value="org.chromium.components.media_router.caf.CastOptionsProvider"/>
<!-- Downloads Google Sans from GMS Core -->
<meta-data android:name="preloaded_fonts"
android:resource="@array/preloaded_google_sans_fonts" />
<!-- Note: All activities directly or indirectly derived from ChromeActivity <!-- Note: All activities directly or indirectly derived from ChromeActivity
must specify android:hardwareAccelerated="false". must specify android:hardwareAccelerated="false".
...@@ -1107,44 +1113,6 @@ by a child template that "extends" this file. ...@@ -1107,44 +1113,6 @@ by a child template that "extends" this file.
android:name="org.chromium.components.payments.PaymentDetailsUpdateService" android:name="org.chromium.components.payments.PaymentDetailsUpdateService"
android:exported="true"/> android:exported="true"/>
<!-- The following service entries exist in order to allow us to
start more than one sandboxed process. -->
<!-- NOTE: If you change the value of "android:process" for the below services,
you also need to update kHelperProcessExecutableName in chrome_constants.cc. -->
{% set num_sandboxed_services = 40 %}
<meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES"
android:value="{{ num_sandboxed_services }}"/>
{% for i in range(num_sandboxed_services) %}
<service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
android:process=":sandboxed_process{{ i }}"
android:permission="{{ manifest_package }}.permission.CHILD_SERVICE"
android:isolatedProcess="true"
android:exported="{{sandboxed_service_exported|default(false)}}"
{% if (i == 0) %}
android:useAppZygote="true"
{% endif %}
{% if (sandboxed_service_exported|default(false)) == 'true' %}
android:externalService="true"
tools:ignore="ExportedService"
android:visibleToInstantApps="true"
{% endif %} />
{% endfor %}
{% set num_privileged_services = 5 %}
<meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
android:value="{{ num_privileged_services }}"/>
{% for i in range(num_privileged_services) %}
{% set privileged_process_name = ':privileged_process%d' % i %}
<service android:name="org.chromium.content.app.PrivilegedProcessService{{ i }}"
android:process="{{ privileged_process_name }}"
android:permission="{{ manifest_package }}.permission.CHILD_SERVICE"
android:isolatedProcess="false"
android:exported="false" />
{% endfor %}
<receiver android:name="org.chromium.chrome.browser.announcement.AnnouncementNotificationManager$Receiver" <receiver android:name="org.chromium.chrome.browser.announcement.AnnouncementNotificationManager$Receiver"
android:exported="false"/> android:exported="false"/>
...@@ -1228,10 +1196,53 @@ by a child template that "extends" this file. ...@@ -1228,10 +1196,53 @@ by a child template that "extends" this file.
android:value="org.chromium.chrome.browser.media.remote.DefaultMediaRouteController"/> android:value="org.chromium.chrome.browser.media.remote.DefaultMediaRouteController"/>
{% endblock %} {% endblock %}
{% endmacro %} {% endmacro %}
{% if skip_definitions is not defined or skip_definitions != 'true' %} {% if not definitions_in_split %}
{{ application_definitions() }} {{ application_definitions() }}
{% endif %} {% endif %}
<!-- The following service entries exist in order to allow us to
start more than one sandboxed process. -->
<!-- NOTE: If you change the value of "android:process" for the below services,
you also need to update kHelperProcessExecutableName in chrome_constants.cc. -->
{% set num_sandboxed_services = 40 %}
<meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES"
android:value="{{ num_sandboxed_services }}"/>
{% for i in range(num_sandboxed_services) %}
<service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
android:process=":sandboxed_process{{ i }}"
android:permission="{{ manifest_package }}.permission.CHILD_SERVICE"
android:isolatedProcess="true"
android:exported="{{sandboxed_service_exported|default(false)}}"
{% if (i == 0) %}
android:useAppZygote="true"
{% endif %}
{% if (sandboxed_service_exported|default(false)) == 'true' %}
android:externalService="true"
tools:ignore="ExportedService"
android:visibleToInstantApps="true"
{% endif %} />
{% endfor %}
{% set num_privileged_services = 5 %}
<meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
android:value="{{ num_privileged_services }}"/>
{% for i in range(num_privileged_services) %}
{% set privileged_process_name = ':privileged_process%d' % i %}
<service android:name="org.chromium.content.app.PrivilegedProcessService{{ i }}"
android:process="{{ privileged_process_name }}"
android:permission="{{ manifest_package }}.permission.CHILD_SERVICE"
android:isolatedProcess="false"
android:exported="false" />
{% endfor %}
<!-- Downloads Google Sans from GMS Core -->
<meta-data android:name="preloaded_fonts"
android:resource="@array/preloaded_google_sans_fonts" />
{% block base_application_definitions %} {% block base_application_definitions %}
{% endblock %} {% endblock %}
{% block extra_application_definitions_for_test %} {% block extra_application_definitions_for_test %}
......
...@@ -8,7 +8,13 @@ ...@@ -8,7 +8,13 @@
## Note: This is a jinja2 template, processed at build time into the final manifest. ## Note: This is a jinja2 template, processed at build time into the final manifest.
## ##
{% block application_name %}org.chromium.chrome.browser.MonochromeApplication{% endblock %} {% block application_name %}
{%- if definitions_in_split -%}
org.chromium.chrome.browser.base.SplitMonochromeApplication
{%- else -%}
org.chromium.chrome.browser.MonochromeApplication
{%- endif -%}
{% endblock %}
## ##
## The below is same as internal version, it seems that jinja doesn't have ## The below is same as internal version, it seems that jinja doesn't have
......
...@@ -7,6 +7,6 @@ package org.chromium.chrome.browser; ...@@ -7,6 +7,6 @@ package org.chromium.chrome.browser;
import org.chromium.components.version_info.VersionConstants; import org.chromium.components.version_info.VersionConstants;
// Constants specific to Chrome. Common constants are in VersionConstants. // Constants specific to Chrome. Common constants are in VersionConstants.
class ChromeVersionConstants extends VersionConstants { public class ChromeVersionConstants extends VersionConstants {
static final String PRODUCT_NAME = "@PRODUCT_FULLNAME@"; static final String PRODUCT_NAME = "@PRODUCT_FULLNAME@";
} }
...@@ -63,5 +63,9 @@ specific_include_rules = { ...@@ -63,5 +63,9 @@ specific_include_rules = {
"MonochromeApplication\.java": [ "MonochromeApplication\.java": [
"+android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java", "+android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java",
"+android_webview/glue/java/src/com/android/webview/chromium/MonochromeLibraryPreloader.java", "+android_webview/glue/java/src/com/android/webview/chromium/MonochromeLibraryPreloader.java",
],
"SplitMonochromeApplication\.java": [
"+android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java",
"+android_webview/glue/java/src/com/android/webview/chromium/MonochromeLibraryPreloader.java",
] ]
} }
...@@ -6,13 +6,12 @@ package org.chromium.chrome.browser; ...@@ -6,13 +6,12 @@ package org.chromium.chrome.browser;
import android.content.Context; import android.content.Context;
import com.android.webview.chromium.MonochromeLibraryPreloader;
import org.chromium.android_webview.nonembedded.WebViewApkApplication; import org.chromium.android_webview.nonembedded.WebViewApkApplication;
import org.chromium.base.ActivityState; import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus;
import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.annotations.UsedByReflection;
import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.chrome.browser.base.SplitMonochromeApplication;
import org.chromium.content_public.browser.ChildProcessCreationParams; import org.chromium.content_public.browser.ChildProcessCreationParams;
/** /**
...@@ -28,50 +27,59 @@ import org.chromium.content_public.browser.ChildProcessCreationParams; ...@@ -28,50 +27,59 @@ import org.chromium.content_public.browser.ChildProcessCreationParams;
* things specific to functioning as a WebView implementation. * things specific to functioning as a WebView implementation.
*/ */
public class MonochromeApplication extends ChromeApplication { public class MonochromeApplication extends ChromeApplication {
@Override public MonochromeApplication() {
protected void attachBaseContext(Context context) { super(new MonochromeApplicationImpl());
super.attachBaseContext(context);
WebViewApkApplication.maybeInitProcessGlobals();
if (!LibraryLoader.getInstance().isLoadedByZygote()) {
LibraryLoader.getInstance().setNativeLibraryPreloader(new MonochromeLibraryPreloader());
}
// ChildProcessCreationParams is only needed for browser process, though it is
// created and set in all processes. We must set isExternalService to true for
// Monochrome because Monochrome's renderer services are shared with WebView
// and are external, and will fail to bind otherwise.
boolean bindToCaller = false;
boolean ignoreVisibilityForImportance = false;
ChildProcessCreationParams.set(getPackageName(), null /* privilegedServicesName */,
getPackageName(), null /* sandboxedServicesName */, true /* isExternalService */,
LibraryProcessType.PROCESS_CHILD, bindToCaller, ignoreVisibilityForImportance);
} }
@Override /** Monochrome application logic. */
public void onCreate() { @UsedByReflection("SplitMonochromeApplication.java")
super.onCreate(); public static class MonochromeApplicationImpl extends ChromeApplication.ChromeApplicationImpl {
if (!ChromeVersionInfo.isStableBuild()) { @UsedByReflection("SplitMonochromeApplication.java")
// Performing Monochrome WebView DevTools Launcher icon showing/hiding logic in onCreate public MonochromeApplicationImpl() {}
// rather than in attachBaseContext() because it depends on application context being
// initiatied. @Override
if (isWebViewProcess()) { public void attachBaseContext(Context context) {
// Whenever a monochrome webview process is launched (WebView service or developer super.attachBaseContext(context);
// UI), post a background task to show/hide the DevTools icon. SplitMonochromeApplication.initializeMonochromeProcessCommon();
WebViewApkApplication.postDeveloperUiLauncherIconTask(); // ChildProcessCreationParams is only needed for browser process, though it is
} else if (isBrowserProcess()) { // created and set in all processes. We must set isExternalService to true for
// Frequently check current system webview provider and show/hide the icon // Monochrome because Monochrome's renderer services are shared with WebView
// accordingly by listening to Monochrome browser Activities status (whenever a // and are external, and will fail to bind otherwise.
// browser activity comes to the foreground). boolean bindToCaller = false;
ApplicationStatus.registerStateListenerForAllActivities((activity, state) -> { boolean ignoreVisibilityForImportance = false;
if (state == ActivityState.STARTED) { ChildProcessCreationParams.set(getApplication().getPackageName(),
WebViewApkApplication.postDeveloperUiLauncherIconTask(); null /* privilegedServicesName */, getApplication().getPackageName(),
} null /* sandboxedServicesName */, true /* isExternalService */,
}); LibraryProcessType.PROCESS_CHILD, bindToCaller, ignoreVisibilityForImportance);
}
@Override
public void onCreate() {
super.onCreate();
if (!ChromeVersionInfo.isStableBuild()) {
// Performing Monochrome WebView DevTools Launcher icon showing/hiding logic in
// onCreate rather than in attachBaseContext() because it depends on application
// context being initiatied.
if (isWebViewProcess()) {
// Whenever a monochrome webview process is launched (WebView service or
// developer UI), post a background task to show/hide the DevTools icon.
WebViewApkApplication.postDeveloperUiLauncherIconTask();
} else if (isBrowserProcess()) {
// Frequently check current system webview provider and show/hide the icon
// accordingly by listening to Monochrome browser Activities status (whenever a
// browser activity comes to the foreground).
ApplicationStatus.registerStateListenerForAllActivities((activity, state) -> {
if (state == ActivityState.STARTED) {
WebViewApkApplication.postDeveloperUiLauncherIconTask();
}
});
}
} }
} }
}
@Override @Override
protected boolean isWebViewProcess() { public boolean isWebViewProcess() {
return WebViewApkApplication.isWebViewProcess(); return WebViewApkApplication.isWebViewProcess();
}
} }
} }
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.base;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import org.chromium.base.compat.ApiHelperForO;
/**
* Application class to use for Chrome when //chrome code is in an isolated split. This class will
* perform any necessary initialization for non-browser processes without loading code from the
* chrome split. In the browser process, the necessary logic is loaded from the chrome split using
* reflection.
*/
public class SplitChromeApplication extends SplitCompatApplication {
private String mChromeApplicationClassName;
public SplitChromeApplication() {
this("org.chromium.chrome.browser.ChromeApplication$ChromeApplicationImpl");
}
public SplitChromeApplication(String chromeApplicationClassName) {
mChromeApplicationClassName = chromeApplicationClassName;
}
@Override
protected void attachBaseContext(Context context) {
if (isBrowserProcess()) {
context = createChromeContext(context);
setImpl(createChromeApplication(context));
} else {
setImpl(createNonBrowserApplication());
}
super.attachBaseContext(context);
}
protected Impl createNonBrowserApplication() {
return new Impl();
}
private Impl createChromeApplication(Context context) {
try {
return (Impl) context.getClassLoader()
.loadClass(mChromeApplicationClassName)
.newInstance();
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
private Context createChromeContext(Context base) {
assert isBrowserProcess();
// Isolated splits are only supported in O+, so just return the base context on other
// versions, since this will have access to all splits.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return base;
}
try {
return ApiHelperForO.createContextForSplit(base, "chrome");
} catch (PackageManager.NameNotFoundException e) {
// This application class should not be used if the chrome split does not exist.
throw new RuntimeException(e);
}
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.base;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import androidx.annotation.CallSuper;
import org.chromium.base.BundleUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.JNIUtils;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.memory.MemoryPressureMonitor;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.browser.ProductConfig;
import org.chromium.components.embedder_support.application.FontPreloadingWorkaround;
import org.chromium.components.module_installer.util.ModuleUtil;
import org.chromium.ui.base.ResourceBundle;
/**
* Application base class which will call through to the given {@link Impl}. Application classes
* which extend this class should also extend {@link Impl}, and call {@link #setImpl(Impl)} before
* calling {@link attachBaseContext(Context)}.
*/
public class SplitCompatApplication extends Application {
private Impl mImpl;
/**
* Holds the implementation of application logic. Will be called by {@link
* SplitCompatApplication}.
*/
protected static class Impl {
private SplitCompatApplication mApplication;
private final void setApplication(SplitCompatApplication application) {
mApplication = application;
}
protected final SplitCompatApplication getApplication() {
return mApplication;
}
@CallSuper
public void onCreate() {
// These can't go in attachBaseContext because Context.getApplicationContext() (which
// they use under-the-hood) does not work until after it returns.
FontPreloadingWorkaround.maybeInstallWorkaround(getApplication());
MemoryPressureMonitor.INSTANCE.registerComponentCallbacks();
}
@CallSuper
public void attachBaseContext(Context context) {
mApplication.superAttachBaseContext(context);
// Perform initialization of globals common to all processes.
ContextUtils.initApplicationContext(getApplication());
maybeInitProcessType();
BundleUtils.setIsBundle(ProductConfig.IS_BUNDLE);
// Write installed modules to crash keys. This needs to be done as early as possible so
// that these values are set before any crashes are reported.
ModuleUtil.updateCrashKeys();
AsyncTask.takeOverAndroidThreadPool();
JNIUtils.setClassLoader(getApplication().getClassLoader());
ResourceBundle.setAvailablePakLocales(
ProductConfig.COMPRESSED_LOCALES, ProductConfig.UNCOMPRESSED_LOCALES);
LibraryLoader.getInstance().setLinkerImplementation(
ProductConfig.USE_CHROMIUM_LINKER, ProductConfig.USE_MODERN_LINKER);
LibraryLoader.getInstance().enableJniChecks();
}
public void onTrimMemory(int level) {}
@CallSuper
public void startActivity(Intent intent, Bundle options) {
mApplication.superStartActivity(intent, options);
}
public void onConfigurationChanged(Configuration newConfig) {}
public boolean isWebViewProcess() {
return false;
}
private void maybeInitProcessType() {
if (isBrowserProcess()) {
LibraryLoader.getInstance().setLibraryProcessType(
LibraryProcessType.PROCESS_BROWSER);
return;
}
// WebView initialization sets the correct process type.
if (isWebViewProcess()) return;
// Child processes set their own process type when bound.
String processName = ContextUtils.getProcessName();
if (processName.contains("privileged_process")
|| processName.contains("sandboxed_process")) {
return;
}
// We must be in an isolated service process.
LibraryLoader.getInstance().setLibraryProcessType(LibraryProcessType.PROCESS_CHILD);
}
}
public final void setImpl(Impl impl) {
assert mImpl == null;
mImpl = impl;
mImpl.setApplication(this);
}
/**
* This exposes the super method so it can be called inside the Impl class code instead of just
* at the start.
*/
private void superAttachBaseContext(Context context) {
super.attachBaseContext(context);
}
/**
* This exposes the super method so it can be called inside the Impl class code instead of just
* at the start.
*/
private void superStartActivity(Intent intent, Bundle options) {
super.startActivity(intent, options);
}
@Override
protected void attachBaseContext(Context context) {
mImpl.attachBaseContext(context);
}
@Override
public void onCreate() {
super.onCreate();
mImpl.onCreate();
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
mImpl.onTrimMemory(level);
}
/** Forward all startActivity() calls to the two argument version. */
@Override
public void startActivity(Intent intent) {
startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, Bundle options) {
mImpl.startActivity(intent, options);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mImpl.onConfigurationChanged(newConfig);
}
public static boolean isBrowserProcess() {
return !ContextUtils.getProcessName().contains(":");
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.base;
import android.content.Context;
import com.android.webview.chromium.MonochromeLibraryPreloader;
import org.chromium.android_webview.nonembedded.WebViewApkApplication;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.chrome.browser.ChromeVersionConstants;
import org.chromium.components.version_info.Channel;
/**
* Application class to use for Monochrome when //chrome code is in an isolated split. See {@link
* SplitChromeApplication} for more info.
*/
public class SplitMonochromeApplication extends SplitChromeApplication {
private static class NonBrowserMonochromeApplication extends Impl {
@Override
public void attachBaseContext(Context context) {
super.attachBaseContext(context);
initializeMonochromeProcessCommon();
}
@Override
public void onCreate() {
super.onCreate();
// TODO(crbug.com/1126301): This matches logic in MonochromeApplication.java.
// Deduplicate if chrome split launches.
if (ChromeVersionConstants.CHANNEL != Channel.STABLE && isWebViewProcess()) {
WebViewApkApplication.postDeveloperUiLauncherIconTask();
}
}
@Override
public boolean isWebViewProcess() {
return WebViewApkApplication.isWebViewProcess();
}
}
public SplitMonochromeApplication() {
super("org.chromium.chrome.browser.MonochromeApplication$MonochromeApplicationImpl");
}
@Override
protected Impl createNonBrowserApplication() {
return new NonBrowserMonochromeApplication();
}
public static void initializeMonochromeProcessCommon() {
WebViewApkApplication.maybeInitProcessGlobals();
if (!LibraryLoader.getInstance().isLoadedByZygote()) {
LibraryLoader.getInstance().setNativeLibraryPreloader(new MonochromeLibraryPreloader());
}
}
}
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