[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_content_browser_client.cc
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chrome_content_browser_client.h"
6
7 #include <iterator>
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <tuple>
12 #include <utility>
13 #include <vector>
14
15 #include "base/base_switches.h"
16 #include "base/command_line.h"
17 #include "base/containers/contains.h"
18 #include "base/containers/fixed_flat_set.h"
19 #include "base/dcheck_is_on.h"
20 #include "base/feature_list.h"
21 #include "base/functional/bind.h"
22 #include "base/functional/callback.h"
23 #include "base/i18n/base_i18n_switches.h"
24 #include "base/i18n/character_encoding.h"
25 #include "base/memory/raw_ptr.h"
26 #include "base/memory/scoped_refptr.h"
27 #include "base/metrics/field_trial_params.h"
28 #include "base/metrics/histogram_functions.h"
29 #include "base/metrics/histogram_macros.h"
30 #include "base/no_destructor.h"
31 #include "base/path_service.h"
32 #include "base/ranges/algorithm.h"
33 #include "base/stl_util.h"
34 #include "base/strings/strcat.h"
35 #include "base/strings/string_number_conversions.h"
36 #include "base/strings/string_piece.h"
37 #include "base/strings/string_split.h"
38 #include "base/strings/string_util.h"
39 #include "base/strings/stringprintf.h"
40 #include "base/task/sequenced_task_runner.h"
41 #include "base/types/expected.h"
42 #include "base/types/expected_macros.h"
43 #include "base/values.h"
44 #include "build/build_config.h"
45 #include "build/chromeos_buildflags.h"
46 #include "chrome/browser/accessibility/accessibility_labels_service.h"
47 #include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
48 #include "chrome/browser/after_startup_task_utils.h"
49 #include "chrome/browser/app_mode/app_mode_utils.h"
50 #include "chrome/browser/bluetooth/chrome_bluetooth_delegate_impl_client.h"
51 #include "chrome/browser/browser_about_handler.h"
52 #include "chrome/browser/browser_features.h"
53 #include "chrome/browser/browser_process.h"
54 #include "chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h"
55 #include "chrome/browser/browsing_topics/browsing_topics_service_factory.h"
56 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
57 #include "chrome/browser/child_process_host_flags.h"
58 #include "chrome/browser/chrome_browser_main_extra_parts_nacl_deprecation.h"
59 #include "chrome/browser/chrome_content_browser_client_binder_policies.h"
60 #include "chrome/browser/chrome_content_browser_client_parts.h"
61 #include "chrome/browser/content_settings/cookie_settings_factory.h"
62 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
63 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
64 #include "chrome/browser/data_saver/data_saver.h"
65 #include "chrome/browser/defaults.h"
66 #include "chrome/browser/device_api/device_service_impl.h"
67 #include "chrome/browser/device_api/managed_configuration_service.h"
68 #include "chrome/browser/download/chrome_download_manager_delegate.h"
69 #include "chrome/browser/download/download_prefs.h"
70 #include "chrome/browser/enterprise/browser_management/management_service_factory.h"
71 #include "chrome/browser/enterprise/connectors/connectors_service.h"
72 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h"
73 #include "chrome/browser/enterprise/reporting/prefs.h"
74 #include "chrome/browser/enterprise/util/managed_browser_utils.h"
75 #include "chrome/browser/extensions/chrome_extension_cookies.h"
76 #include "chrome/browser/external_protocol/external_protocol_handler.h"
77 #include "chrome/browser/favicon/favicon_utils.h"
78 #include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h"
79 #include "chrome/browser/font_family_cache.h"
80 #include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h"
81 #include "chrome/browser/hid/chrome_hid_delegate.h"
82 #include "chrome/browser/interstitials/enterprise_util.h"
83 #include "chrome/browser/lifetime/browser_shutdown.h"
84 #include "chrome/browser/lookalikes/lookalike_url_navigation_throttle.h"
85 #include "chrome/browser/media/audio_service_util.h"
86 #include "chrome/browser/media/router/media_router_feature.h"
87 #include "chrome/browser/media/webrtc/audio_debug_recordings_handler.h"
88 #include "chrome/browser/media/webrtc/capture_policy_utils.h"
89 #include "chrome/browser/media/webrtc/chrome_screen_enumerator.h"
90 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
91 #include "chrome/browser/media/webrtc/media_device_salt_service_factory.h"
92 #include "chrome/browser/media/webrtc/webrtc_logging_controller.h"
93 #include "chrome/browser/memory/chrome_browser_main_extra_parts_memory.h"
94 #include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h"
95 #include "chrome/browser/metrics/chrome_feature_list_creator.h"
96 #include "chrome/browser/navigation_predictor/anchor_element_preloader.h"
97 #include "chrome/browser/net/chrome_network_delegate.h"
98 #include "chrome/browser/net/profile_network_context_service.h"
99 #include "chrome/browser/net/profile_network_context_service_factory.h"
100 #include "chrome/browser/net/system_network_context_manager.h"
101 #include "chrome/browser/optimization_guide/chrome_browser_main_extra_parts_optimization_guide.h"
102 #include "chrome/browser/payments/payment_request_display_manager_factory.h"
103 #include "chrome/browser/performance_manager/public/chrome_browser_main_extra_parts_performance_manager.h"
104 #include "chrome/browser/performance_manager/public/chrome_content_browser_client_performance_manager_part.h"
105 #include "chrome/browser/performance_monitor/chrome_browser_main_extra_parts_performance_monitor.h"
106 #include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h"
107 #include "chrome/browser/plugins/plugin_utils.h"
108 #include "chrome/browser/policy/policy_util.h"
109 #include "chrome/browser/policy/profile_policy_connector.h"
110 #include "chrome/browser/preloading/navigation_ablation_throttle.h"
111 #include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h"
112 #include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_speculation_host_delegate.h"
113 #include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
114 #include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_navigation_throttle.h"
115 #include "chrome/browser/preloading/prefetch/prefetch_service/chrome_prefetch_service_delegate.h"
116 #include "chrome/browser/preloading/prefetch/search_prefetch/field_trial_settings.h"
117 #include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_url_loader.h"
118 #include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h"
119 #include "chrome/browser/preloading/preloading_features.h"
120 #include "chrome/browser/preloading/preloading_prefs.h"
121 #include "chrome/browser/preloading/prerender/prerender_web_contents_delegate.h"
122 #include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
123 #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h"
124 #include "chrome/browser/private_network_access/chrome_private_network_device_delegate.h"
125 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
126 #include "chrome/browser/profiles/profile.h"
127 #include "chrome/browser/profiles/profile_io_data.h"
128 #include "chrome/browser/profiles/profile_manager.h"
129 #include "chrome/browser/profiles/profile_selections.h"
130 #include "chrome/browser/profiles/renderer_updater.h"
131 #include "chrome/browser/profiles/renderer_updater_factory.h"
132 #include "chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.h"
133 #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h"
134 #include "chrome/browser/renderer_preferences_util.h"
135 #include "chrome/browser/safe_browsing/certificate_reporting_service.h"
136 #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h"
137 #include "chrome/browser/safe_browsing/chrome_ping_manager_factory.h"
138 #include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h"
139 #include "chrome/browser/safe_browsing/delayed_warning_navigation_throttle.h"
140 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
141 #include "chrome/browser/safe_browsing/url_checker_delegate_impl.h"
142 #include "chrome/browser/safe_browsing/url_lookup_service_factory.h"
143 #include "chrome/browser/search/search.h"
144 #include "chrome/browser/segmentation_platform/chrome_browser_main_extra_parts_segmentation_platform.h"
145 #include "chrome/browser/sharing/sms/sms_remote_fetcher.h"
146 #include "chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h"
147 #include "chrome/browser/signin/chrome_signin_url_loader_throttle.h"
148 #include "chrome/browser/signin/header_modification_delegate_impl.h"
149 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h"
150 #include "chrome/browser/ssl/chrome_security_blocking_page_factory.h"
151 #include "chrome/browser/ssl/https_defaulted_callbacks.h"
152 #include "chrome/browser/ssl/https_upgrades_interceptor.h"
153 #include "chrome/browser/ssl/https_upgrades_navigation_throttle.h"
154 #include "chrome/browser/ssl/sct_reporting_service.h"
155 #include "chrome/browser/ssl/ssl_client_auth_metrics.h"
156 #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
157 #include "chrome/browser/ssl/typed_navigation_upgrade_throttle.h"
158 #include "chrome/browser/task_manager/sampling/task_manager_impl.h"
159 #include "chrome/browser/tracing/chrome_tracing_delegate.h"
160 #include "chrome/browser/translate/translate_service.h"
161 #include "chrome/browser/ui/blocked_content/blocked_window_params.h"
162 #include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h"
163 #include "chrome/browser/ui/blocked_content/tab_under_navigation_throttle.h"
164 #include "chrome/browser/ui/browser_navigator.h"
165 #include "chrome/browser/ui/browser_navigator_params.h"
166 #include "chrome/browser/ui/chrome_select_file_policy.h"
167 #include "chrome/browser/ui/login/login_handler.h"
168 #include "chrome/browser/ui/login/login_navigation_throttle.h"
169 #include "chrome/browser/ui/login/login_tab_helper.h"
170 #include "chrome/browser/ui/passwords/password_manager_navigation_throttle.h"
171 #include "chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h"
172 #include "chrome/browser/ui/prefs/pref_watcher.h"
173 #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
174 #include "chrome/browser/ui/ui_features.h"
175 #include "chrome/browser/ui/webid/identity_dialog_controller.h"
176 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
177 #include "chrome/browser/ui/webui/log_web_ui_url.h"
178 #include "chrome/browser/universal_web_contents_observers.h"
179 #include "chrome/browser/usb/chrome_usb_delegate.h"
180 #include "chrome/browser/vr/vr_tab_helper.h"
181 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
182 #include "chrome/browser/webapps/web_app_offline.h"
183 #include "chrome/browser/webauthn/webauthn_pref_names.h"
184 #include "chrome/common/buildflags.h"
185 #include "chrome/common/channel_info.h"
186 #include "chrome/common/chrome_constants.h"
187 #include "chrome/common/chrome_content_client.h"
188 #include "chrome/common/chrome_features.h"
189 #include "chrome/common/chrome_paths.h"
190 #include "chrome/common/chrome_paths_internal.h"
191 #include "chrome/common/chrome_switches.h"
192 #include "chrome/common/env_vars.h"
193 #include "chrome/common/google_url_loader_throttle.h"
194 #include "chrome/common/logging_chrome.h"
195 #include "chrome/common/pdf_util.h"
196 #include "chrome/common/ppapi_utils.h"
197 #include "chrome/common/pref_names.h"
198 #include "chrome/common/profiler/thread_profiler_configuration.h"
199 #include "chrome/common/renderer_configuration.mojom.h"
200 #include "chrome/common/secure_origin_allowlist.h"
201 #include "chrome/common/url_constants.h"
202 #include "chrome/common/webui_url_constants.h"
203 #include "chrome/grit/generated_resources.h"
204 #include "chrome/installer/util/google_update_settings.h"
205 #include "components/autofill/core/common/autofill_switches.h"
206 #include "components/blocked_content/popup_blocker.h"
207 #include "components/browsing_topics/browsing_topics_service.h"
208 #include "components/captive_portal/core/buildflags.h"
209 #include "components/content_settings/browser/page_specific_content_settings.h"
210 #include "components/content_settings/core/browser/cookie_settings.h"
211 #include "components/content_settings/core/browser/host_content_settings_map.h"
212 #include "components/content_settings/core/browser/private_network_settings.h"
213 #include "components/content_settings/core/common/content_settings.h"
214 #include "components/content_settings/core/common/content_settings_types.h"
215 #include "components/custom_handlers/protocol_handler_registry.h"
216 #include "components/custom_handlers/protocol_handler_throttle.h"
217 #include "components/dom_distiller/core/dom_distiller_switches.h"
218 #include "components/dom_distiller/core/url_constants.h"
219 #include "components/embedder_support/content_settings_utils.h"
220 #include "components/embedder_support/origin_trials/origin_trials_settings_storage.h"
221 #include "components/embedder_support/switches.h"
222 #include "components/embedder_support/user_agent_utils.h"
223 #include "components/enterprise/common/proto/connectors.pb.h"
224 #include "components/enterprise/content/clipboard_restriction_service.h"
225 #include "components/enterprise/content/pref_names.h"
226 #include "components/error_page/common/error.h"
227 #include "components/error_page/common/error_page_switches.h"
228 #include "components/error_page/common/localized_error.h"
229 #include "components/error_page/content/browser/net_error_auto_reloader.h"
230 #include "components/google/core/common/google_switches.h"
231 #include "components/keep_alive_registry/keep_alive_types.h"
232 #include "components/keep_alive_registry/scoped_keep_alive.h"
233 #include "components/language/core/browser/pref_names.h"
234 #include "components/lens/buildflags.h"
235 #include "components/live_caption/caption_util.h"
236 #include "components/media_device_salt/media_device_salt_service.h"
237 #include "components/media_router/browser/presentation/presentation_service_delegate_impl.h"
238 #include "components/media_router/browser/presentation/receiver_presentation_service_delegate_impl.h"
239 #include "components/media_router/browser/presentation/web_contents_presentation_manager.h"
240 #include "components/metrics/client_info.h"
241 #include "components/metrics_services_manager/metrics_services_manager.h"
242 #include "components/net_log/chrome_net_log.h"
243 #include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
244 #include "components/no_state_prefetch/common/no_state_prefetch_final_status.h"
245 #include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
246 #include "components/omnibox/common/omnibox_features.h"
247 #include "components/page_load_metrics/browser/metrics_navigation_throttle.h"
248 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
249 #include "components/payments/content/payment_handler_navigation_throttle.h"
250 #include "components/payments/content/payment_request_display_manager.h"
251 #include "components/performance_manager/embedder/performance_manager_registry.h"
252 #include "components/permissions/bluetooth_delegate_impl.h"
253 #include "components/permissions/permission_context_base.h"
254 #include "components/policy/content/policy_blocklist_navigation_throttle.h"
255 #include "components/policy/content/policy_blocklist_service.h"
256 #include "components/policy/core/common/management/management_service.h"
257 #include "components/policy/core/common/policy_pref_names.h"
258 #include "components/pref_registry/pref_registry_syncable.h"
259 #include "components/prefs/pref_registry_simple.h"
260 #include "components/prefs/pref_service.h"
261 #include "components/prefs/scoped_user_pref_update.h"
262 #include "components/privacy_sandbox/privacy_sandbox_features.h"
263 #include "components/privacy_sandbox/privacy_sandbox_prefs.h"
264 #include "components/privacy_sandbox/privacy_sandbox_settings.h"
265 #include "components/safe_browsing/content/browser/browser_url_loader_throttle.h"
266 #include "components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h"
267 #include "components/safe_browsing/content/browser/safe_browsing_navigation_throttle.h"
268 #include "components/safe_browsing/content/browser/ui_manager.h"
269 #include "components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h"
270 #include "components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_utils.h"
271 #include "components/safe_browsing/core/browser/ping_manager.h"
272 #include "components/safe_browsing/core/browser/realtime/policy_engine.h"
273 #include "components/safe_browsing/core/browser/realtime/url_lookup_service.h"
274 #include "components/safe_browsing/core/browser/url_checker_delegate.h"
275 #include "components/safe_browsing/core/common/features.h"
276 #include "components/safe_browsing/core/common/safe_browsing_prefs.h"
277 #include "components/security_interstitials/content/insecure_form_navigation_throttle.h"
278 #include "components/security_interstitials/content/ssl_cert_reporter.h"
279 #include "components/security_interstitials/content/ssl_error_handler.h"
280 #include "components/security_interstitials/content/ssl_error_navigation_throttle.h"
281 #include "components/services/storage/public/cpp/storage_prefs.h"
282 #include "components/site_isolation/pref_names.h"
283 #include "components/site_isolation/preloaded_isolated_origins.h"
284 #include "components/site_isolation/site_isolation_policy.h"
285 #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
286 #include "components/supervised_user/core/common/buildflags.h"
287 #include "components/translate/core/common/translate_switches.h"
288 #include "components/variations/variations_associated_data.h"
289 #include "components/variations/variations_switches.h"
290 #include "components/webapps/common/web_app_id.h"
291 #include "content/public/browser/attribution_data_model.h"
292 #include "content/public/browser/browser_accessibility_state.h"
293 #include "content/public/browser/browser_child_process_host.h"
294 #include "content/public/browser/browser_context.h"
295 #include "content/public/browser/browser_main_parts.h"
296 #include "content/public/browser/browser_ppapi_host.h"
297 #include "content/public/browser/browser_task_traits.h"
298 #include "content/public/browser/browser_thread.h"
299 #include "content/public/browser/browser_url_handler.h"
300 #include "content/public/browser/certificate_request_result_type.h"
301 #include "content/public/browser/child_process_data.h"
302 #include "content/public/browser/child_process_security_policy.h"
303 #include "content/public/browser/client_certificate_delegate.h"
304 #include "content/public/browser/file_url_loader.h"
305 #include "content/public/browser/isolated_web_apps_policy.h"
306 #include "content/public/browser/navigation_handle.h"
307 #include "content/public/browser/navigation_throttle.h"
308 #include "content/public/browser/overlay_window.h"
309 #include "content/public/browser/permission_controller.h"
310 #include "content/public/browser/render_frame_host.h"
311 #include "content/public/browser/render_process_host.h"
312 #include "content/public/browser/site_isolation_mode.h"
313 #include "content/public/browser/sms_fetcher.h"
314 #include "content/public/browser/tts_controller.h"
315 #include "content/public/browser/tts_platform.h"
316 #include "content/public/browser/url_loader_request_interceptor.h"
317 #include "content/public/browser/vpn_service_proxy.h"
318 #include "content/public/browser/weak_document_ptr.h"
319 #include "content/public/browser/web_contents.h"
320 #include "content/public/browser/web_contents_delegate.h"
321 #include "content/public/browser/web_contents_view_delegate.h"
322 #include "content/public/browser/web_ui_url_loader_factory.h"
323 #include "content/public/browser/webui_config_map.h"
324 #include "content/public/common/content_descriptors.h"
325 #include "content/public/common/content_features.h"
326 #include "content/public/common/content_switches.h"
327 #include "content/public/common/window_container_type.mojom-shared.h"
328 #include "device/vr/buildflags/buildflags.h"
329 #include "extensions/buildflags/buildflags.h"
330 #include "google_apis/gaia/gaia_urls.h"
331 #include "google_apis/google_api_keys.h"
332 #include "gpu/config/gpu_switches.h"
333 #include "media/base/media_switches.h"
334 #include "media/media_buildflags.h"
335 #include "media/mojo/buildflags.h"
336 #include "mojo/public/cpp/bindings/remote.h"
337 #include "net/base/features.h"
338 #include "net/cookies/site_for_cookies.h"
339 #include "net/ssl/client_cert_store.h"
340 #include "net/ssl/ssl_cert_request_info.h"
341 #include "net/ssl/ssl_private_key.h"
342 #include "pdf/buildflags.h"
343 #include "ppapi/buildflags/buildflags.h"
344 #include "printing/buildflags/buildflags.h"
345 #include "sandbox/policy/features.h"
346 #include "sandbox/policy/mojom/sandbox.mojom.h"
347 #include "sandbox/policy/switches.h"
348 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
349 #include "services/metrics/public/cpp/ukm_source_id.h"
350 #include "services/network/public/cpp/features.h"
351 #include "services/network/public/cpp/is_potentially_trustworthy.h"
352 #include "services/network/public/cpp/network_switches.h"
353 #include "services/network/public/cpp/resource_request.h"
354 #include "services/network/public/cpp/self_deleting_url_loader_factory.h"
355 #include "services/network/public/cpp/web_sandbox_flags.h"
356 #include "services/network/public/mojom/network_service.mojom.h"
357 #include "services/network/public/mojom/web_transport.mojom.h"
358 #include "third_party/blink/public/common/features.h"
359 #include "third_party/blink/public/common/loader/url_loader_throttle.h"
360 #include "third_party/blink/public/common/navigation/navigation_policy.h"
361 #include "third_party/blink/public/common/permissions/permission_utils.h"
362 #include "third_party/blink/public/common/permissions_policy/permissions_policy.h"
363 #include "third_party/blink/public/common/switches.h"
364 #include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h"
365 #include "third_party/blink/public/public_buildflags.h"
366 #include "third_party/widevine/cdm/buildflags.h"
367 #include "ui/base/clipboard/clipboard_format_type.h"
368 #include "ui/base/l10n/l10n_util.h"
369 #include "ui/base/page_transition_types.h"
370 #include "ui/base/resource/resource_bundle.h"
371 #include "ui/color/color_provider_key.h"
372 #include "ui/gfx/switches.h"
373 #include "ui/native_theme/native_theme.h"
374 #include "url/gurl.h"
375 #include "url/origin.h"
376 #include "url/third_party/mozilla/url_parse.h"
377 #include "url/url_constants.h"
378
379 #if BUILDFLAG(IS_WIN)
380 #include "base/files/file_util.h"
381 #include "base/strings/string_tokenizer.h"
382 #include "base/win/win_util.h"
383 #include "base/win/windows_version.h"
384 #include "chrome/browser/chrome_browser_main_win.h"
385 #include "chrome/browser/enterprise/platform_auth/platform_auth_navigation_throttle.h"
386 #include "chrome/browser/lifetime/application_lifetime_desktop.h"
387 #include "chrome/install_static/install_util.h"
388 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
389 #include "sandbox/win/src/sandbox_policy.h"
390 #elif BUILDFLAG(IS_MAC)
391 #include "chrome/browser/browser_process_platform_part_mac.h"
392 #include "chrome/browser/chrome_browser_main_mac.h"
393 #include "chrome/browser/mac/auth_session_request.h"
394 #include "chrome/browser/mac/chrome_browser_main_extra_parts_mac.h"
395 #include "components/soda/constants.h"
396 #include "sandbox/mac/sandbox_compiler.h"
397 #include "sandbox/policy/mac/params.h"
398 #include "sandbox/policy/mac/sandbox_mac.h"
399 #elif BUILDFLAG(IS_CHROMEOS_ASH)
400 #include "ash/constants/ash_features.h"
401 #include "ash/constants/ash_pref_names.h"
402 #include "ash/constants/ash_switches.h"
403 #include "ash/public/cpp/tablet_mode.h"
404 #include "ash/webui/camera_app_ui/url_constants.h"
405 #include "ash/webui/help_app_ui/url_constants.h"
406 #include "ash/webui/media_app_ui/url_constants.h"
407 #include "ash/webui/scanning/url_constants.h"
408 #include "chrome/app/chrome_crash_reporter_client.h"
409 #include "chrome/browser/apps/app_service/app_install/app_install_navigation_throttle.h"
410 #include "chrome/browser/ash/arc/fileapi/arc_content_file_system_backend_delegate.h"
411 #include "chrome/browser/ash/arc/fileapi/arc_documents_provider_backend_delegate.h"
412 #include "chrome/browser/ash/chrome_browser_main_parts_ash.h"
413 #include "chrome/browser/ash/crosapi/browser_util.h"
414 #include "chrome/browser/ash/drive/fileapi/drivefs_file_system_backend_delegate.h"
415 #include "chrome/browser/ash/file_manager/app_id.h"
416 #include "chrome/browser/ash/file_system_provider/fileapi/backend_delegate.h"
417 #include "chrome/browser/ash/fileapi/external_file_url_loader_factory.h"
418 #include "chrome/browser/ash/fileapi/file_system_backend.h"
419 #include "chrome/browser/ash/fileapi/mtp_file_system_backend_delegate.h"
420 #include "chrome/browser/ash/login/signin/merge_session_navigation_throttle.h"
421 #include "chrome/browser/ash/login/signin/merge_session_throttling_utils.h"
422 #include "chrome/browser/ash/login/signin_partition_manager.h"
423 #include "chrome/browser/ash/login/startup_utils.h"
424 #include "chrome/browser/ash/net/network_health/network_health_manager.h"
425 #include "chrome/browser/ash/net/system_proxy_manager.h"
426 #include "chrome/browser/ash/profiles/profile_helper.h"
427 #include "chrome/browser/ash/smb_client/fileapi/smbfs_file_system_backend_delegate.h"
428 #include "chrome/browser/ash/system/input_device_settings.h"
429 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
430 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
431 #include "chrome/browser/ash/url_handler.h"
432 #include "chrome/browser/chromeos/app_mode/kiosk_settings_navigation_throttle.h"
433 #include "chrome/browser/speech/tts_chromeos.h"
434 #include "chrome/browser/speech/tts_controller_delegate_impl.h"
435 #include "chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h"
436 #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
437 #include "chrome/browser/ui/browser_dialogs.h"
438 #include "chrome/browser/ui/webui/ash/kerberos/kerberos_in_browser_dialog.h"
439 #include "chrome/common/webui_url_constants.h"
440 #include "chromeos/ash/components/browser_context_helper/browser_context_types.h"
441 #include "chromeos/ash/services/network_health/public/cpp/network_health_helper.h"
442 #include "components/crash/core/app/breakpad_linux.h"
443 #include "components/user_manager/user.h"
444 #include "components/user_manager/user_manager.h"
445 #include "services/service_manager/public/mojom/interface_provider_spec.mojom.h"
446 #include "storage/browser/file_system/external_mount_points.h"
447 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
448 // of lacros-chrome is complete.
449 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
450 #include "chrome/browser/chrome_browser_main_linux.h"
451 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h"
452 #elif BUILDFLAG(IS_ANDROID)
453 #include "base/android/application_status_listener.h"
454 #include "base/android/build_info.h"
455 #include "base/feature_list.h"
456 #include "chrome/android/features/dev_ui/buildflags.h"
457 #include "chrome/browser/android/customtabs/client_data_header_web_contents_observer.h"
458 #include "chrome/browser/android/devtools_manager_delegate_android.h"
459 #include "chrome/browser/android/ntp/new_tab_page_url_handler.h"
460 #include "chrome/browser/android/service_tab_launcher.h"
461 #include "chrome/browser/android/tab_android.h"
462 #include "chrome/browser/android/tab_web_contents_delegate_android.h"
463 #include "chrome/browser/chrome_browser_main_android.h"
464 #include "chrome/browser/download/android/available_offline_content_provider.h"
465 #include "chrome/browser/download/android/intercept_oma_download_navigation_throttle.h"
466 #include "chrome/browser/flags/android/chrome_feature_list.h"
467 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
468 #include "chrome/common/chrome_descriptors.h"
469 #include "components/browser_ui/accessibility/android/font_size_prefs_android.h"
470 #include "components/crash/content/browser/child_exit_observer_android.h"
471 #include "components/crash/content/browser/crash_memory_metrics_collector_android.h"
472 #include "components/navigation_interception/intercept_navigation_delegate.h"
473 #include "components/viz/common/features.h"
474 #include "components/viz/common/viz_utils.h"
475 #include "content/public/browser/android/java_interfaces.h"
476 #include "services/service_manager/public/cpp/interface_provider.h"
477 #include "ui/base/resource/resource_bundle_android.h"
478 #include "ui/base/ui_base_paths.h"
479 #include "ui/display/util/display_util.h"
480 #if BUILDFLAG(DFMIFY_DEV_UI)
481 #include "chrome/browser/dev_ui/android/dev_ui_loader_throttle.h"
482 #endif  // BUILDFLAG(DFMIFY_DEV_UI)
483 #elif BUILDFLAG(IS_POSIX)
484 #include "chrome/browser/chrome_browser_main_posix.h"
485 #elif BUILDFLAG(IS_FUCHSIA)
486 #include "chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h"
487 #endif
488
489 #if BUILDFLAG(IS_CHROMEOS)
490 #include "base/debug/leak_annotations.h"
491 #include "chrome/browser/apps/intent_helper/chromeos_disabled_apps_throttle.h"
492 #include "chrome/browser/apps/link_capturing/chromeos_link_capturing_delegate.h"
493 #include "chrome/browser/chromeos/enterprise/incognito_navigation_throttle.h"
494 #include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
495 #include "chrome/browser/chromeos/quickoffice/quickoffice_prefs.h"
496 #include "chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part.h"
497 #include "chrome/browser/file_system_access/cloud_identifier/cloud_identifier_util_cros.h"
498 #include "chrome/browser/policy/networking/policy_cert_service.h"
499 #include "chrome/browser/policy/networking/policy_cert_service_factory.h"
500 #include "chrome/browser/policy/system_features_disable_list_policy_handler.h"
501 #include "chrome/browser/smart_card/chromeos_smart_card_delegate.h"
502 #include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h"
503 #include "chromeos/components/kiosk/kiosk_utils.h"
504 #include "chromeos/constants/chromeos_features.h"
505 #include "components/crash/core/app/breakpad_linux.h"
506 #include "third_party/cros_system_api/switches/chrome_switches.h"
507 #endif
508
509 #if !BUILDFLAG(IS_ANDROID)
510 #include "chrome/browser/apps/link_capturing/link_capturing_navigation_throttle.h"
511 #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h"
512 #include "chrome/browser/devtools/devtools_window.h"
513 #include "chrome/browser/direct_sockets/chrome_direct_sockets_delegate.h"
514 #include "chrome/browser/headless/chrome_browser_main_extra_parts_headless.h"
515 #include "chrome/browser/media/unified_autoplay_config.h"
516 #include "chrome/browser/metrics/chrome_responsiveness_calculator_delegate.h"
517 #include "chrome/browser/new_tab_page/new_tab_page_util.h"
518 #include "chrome/browser/page_info/about_this_site_side_panel_throttle.h"
519 #include "chrome/browser/search/instant_service.h"
520 #include "chrome/browser/search/instant_service_factory.h"
521 #include "chrome/browser/serial/chrome_serial_delegate.h"
522 #include "chrome/browser/task_manager/task_manager_interface.h"
523 #include "chrome/browser/ui/browser.h"
524 #include "chrome/browser/ui/browser_dialogs.h"
525 #include "chrome/browser/ui/browser_finder.h"
526 #include "chrome/browser/ui/chrome_pages.h"
527 #include "chrome/browser/ui/search/new_tab_page_navigation_throttle.h"
528 #include "chrome/browser/ui/web_applications/tabbed_web_app_navigation_throttle.h"
529 #include "chrome/browser/ui/web_applications/webui_web_app_navigation_throttle.h"
530 #include "chrome/browser/ui/webui/chrome_content_browser_client_webui_part.h"
531 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_error_page.h"
532 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory.h"
533 #include "chrome/browser/web_applications/policy/web_app_policy_manager.h"
534 #include "chrome/browser/web_applications/web_app_helpers.h"
535 #include "chrome/browser/web_applications/web_app_provider.h"
536 #include "chrome/browser/web_applications/web_app_registrar.h"
537 #include "chrome/browser/web_applications/web_app_utils.h"
538 #include "chrome/browser/webauthn/authenticator_request_scheduler.h"
539 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
540 #include "chrome/grit/chrome_unscaled_resources.h"  // nogncheck crbug.com/1125897
541 #include "components/commerce/core/commerce_feature_list.h"
542 #include "components/media_effects/media_effects_manager_binder.h"
543 #include "components/password_manager/content/common/web_ui_constants.h"
544 #include "components/password_manager/core/common/password_manager_features.h"
545 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
546 #endif  //  !BUILDFLAG(IS_ANDROID)
547
548 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
549 // of lacros-chrome is complete.
550 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \
551     (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
552 #include "chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h"
553 #endif
554
555 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
556 #include "components/crash/core/app/crash_switches.h"
557 #include "components/crash/core/app/crashpad.h"
558 #endif
559
560 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
561 #include "components/crash/content/browser/crash_handler_host_linux.h"
562 #else
563 #include "chrome/browser/apps/link_capturing/web_app_link_capturing_delegate.h"
564 #endif
565
566 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
567 #include "chrome/browser/enterprise/chrome_browser_main_extra_parts_enterprise.h"
568 #include "chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.h"
569 #include "chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h"
570 #endif
571
572 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
573     BUILDFLAG(IS_CHROMEOS_ASH)
574 #include "chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h"
575 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) ||
576         // BUILDFLAG(IS_CHROMEOS_ASH)
577
578 #if defined(TOOLKIT_VIEWS)
579 #include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
580 #include "chrome/browser/ui/side_search/side_search_utils.h"
581 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h"
582 #endif
583
584 #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
585 #include "chrome/browser/ui/lens/lens_side_panel_navigation_helper.h"
586 #include "components/lens/lens_features.h"
587 #endif
588
589 #if BUILDFLAG(IS_LINUX)
590 #include "chrome/browser/chrome_browser_main_extra_parts_linux.h"
591 #elif BUILDFLAG(IS_OZONE)
592 #include "chrome/browser/chrome_browser_main_extra_parts_ozone.h"
593 #endif
594
595 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
596 #include "components/captive_portal/content/captive_portal_tab_helper.h"
597 #include "components/captive_portal/content/captive_portal_url_loader_throttle.h"
598 #endif
599
600 #if BUILDFLAG(ENABLE_NACL)
601 #include "components/nacl/browser/nacl_host_message_filter.h"
602 #include "components/nacl/browser/nacl_process_host.h"
603 #include "components/nacl/common/nacl_process_type.h"
604 #include "components/nacl/common/nacl_switches.h"
605 #endif
606
607 #if BUILDFLAG(ENABLE_EXTENSIONS)
608 #include "chrome/browser/accessibility/animation_policy_prefs.h"
609 #include "chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h"
610 #include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h"
611 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
612 #include "chrome/browser/extensions/extension_util.h"
613 #include "chrome/browser/extensions/user_script_listener.h"
614 #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h"
615 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
616 #include "chrome/browser/web_applications/web_app_utils.h"
617 #include "content/public/browser/site_isolation_policy.h"
618 #include "extensions/browser/api/web_request/web_request_api.h"
619 #include "extensions/browser/api/web_request/web_request_proxying_webtransport.h"
620 #include "extensions/browser/extension_navigation_throttle.h"
621 #include "extensions/browser/extension_protocols.h"
622 #include "extensions/browser/extension_registry.h"
623 #include "extensions/browser/extension_util.h"
624 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
625 #include "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
626 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
627 #include "extensions/browser/process_map.h"
628 #include "extensions/browser/script_injection_tracker.h"
629 #include "extensions/common/constants.h"
630 #include "extensions/common/extension.h"
631 #include "extensions/common/extension_set.h"
632 #include "extensions/common/manifest_handlers/background_info.h"
633 #include "extensions/common/permissions/permissions_data.h"
634 #include "extensions/common/switches.h"
635 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
636
637 #if BUILDFLAG(ENABLE_PLUGINS)
638 #include "chrome/browser/plugins/chrome_content_browser_client_plugins_part.h"
639 #include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h"
640 #endif
641
642 #if BUILDFLAG(ENABLE_PDF)
643 #include "chrome/browser/pdf/chrome_pdf_stream_delegate.h"
644 #include "components/pdf/browser/pdf_navigation_throttle.h"
645 #include "components/pdf/browser/pdf_url_loader_request_interceptor.h"
646 #include "components/pdf/common/internal_plugin_helpers.h"
647 #endif  // BUILDFLAG(ENABLE_PDF)
648
649 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
650 #include "chrome/browser/supervised_user/supervised_user_google_auth_navigation_throttle.h"
651 #endif
652
653 #if BUILDFLAG(ENABLE_MEDIA_REMOTING)
654 #include "chrome/browser/media/cast_remoting_connector.h"
655 #endif
656
657 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
658 #include "chrome/browser/supervised_user/supervised_user_navigation_throttle.h"
659 #endif
660
661 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
662 #include "chrome/browser/safe_browsing/chrome_password_protection_service.h"
663 #endif
664
665 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
666 #include "chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h"  // nogncheck crbug.com/1125897
667 #include "chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.h"  // nogncheck crbug.com/1125897
668 #endif
669
670 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
671 #include "chrome/browser/offline_pages/offline_page_navigation_throttle.h"
672 #include "chrome/browser/offline_pages/offline_page_tab_helper.h"
673 #include "chrome/browser/offline_pages/offline_page_url_loader_request_interceptor.h"
674 #endif
675
676 #if BUILDFLAG(FULL_SAFE_BROWSING)
677 #include "chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h"
678 #endif
679
680 #if BUILDFLAG(ENABLE_VR)
681 #include "chrome/browser/vr/chrome_xr_integration_client.h"
682 #endif
683
684 #if BUILDFLAG(IS_CHROMEOS_LACROS)
685 #include "chrome/browser/chrome_browser_main_parts_lacros.h"
686 #include "chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h"
687 #include "chrome/browser/speech/tts_lacros.h"
688 #include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_lacros.h"
689 #include "chrome/common/chrome_descriptors.h"
690 #include "chromeos/crosapi/mojom/kerberos_in_browser.mojom.h"
691 #include "chromeos/lacros/lacros_service.h"
692 #include "chromeos/startup/browser_init_params.h"
693 #include "chromeos/startup/browser_postlogin_params.h"
694 #include "chromeos/startup/startup.h"           // nogncheck
695 #include "chromeos/startup/startup_switches.h"  // nogncheck
696 #include "mojo/core/embedder/embedder.h"
697 #include "ui/base/ui_base_switches.h"
698 #endif
699
700 #if BUILDFLAG(USE_MINIKIN_HYPHENATION) && !BUILDFLAG(IS_ANDROID)
701 #include "chrome/browser/component_updater/hyphenation_component_installer.h"
702 #endif
703
704 #if BUILDFLAG(FULL_SAFE_BROWSING)
705 #include "components/enterprise/common/files_scan_data.h"
706 #endif
707
708 // This should be after all other #includes.
709 #if defined(_WINDOWS_)  // Detect whether windows.h was included.
710 #include "base/win/windows_h_disallowed.h"
711 #endif  // defined(_WINDOWS_)
712
713 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
714 #include "chrome/browser/accessibility/accessibility_state_utils.h"
715 #include "chrome/browser/accessibility/pdf_ocr_controller.h"
716 #include "chrome/browser/accessibility/pdf_ocr_controller_factory.h"
717 #include "components/services/screen_ai/public/cpp/utilities.h"
718 #endif
719
720 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) || !BUILDFLAG(IS_CHROMEOS_ASH)
721 #include "ui/accessibility/accessibility_features.h"
722 #endif
723
724 #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
725 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service.h"
726 #include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.h"
727 #include "chrome/browser/signin/bound_session_credentials/bound_session_request_throttled_listener_browser_impl.h"
728 #include "chrome/common/bound_session_request_throttled_listener.h"
729 #endif  // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
730
731 #if BUILDFLAG(IS_CHROMEOS)
732 #include "chromeos/components/kiosk/kiosk_utils.h"
733 #endif  // BUILDFLAG(IS_CHROMEOS)
734
735 using blink::mojom::EffectiveConnectionType;
736 using blink::web_pref::WebPreferences;
737 using content::BrowserThread;
738 using content::BrowserURLHandler;
739 using content::ChildProcessSecurityPolicy;
740 using content::RenderFrameHost;
741 using content::SiteInstance;
742 using content::WebContents;
743
744 #if BUILDFLAG(IS_POSIX)
745 using content::PosixFileDescriptorInfo;
746 #endif
747
748 #if BUILDFLAG(ENABLE_EXTENSIONS)
749 using extensions::APIPermission;
750 using extensions::ChromeContentBrowserClientExtensionsPart;
751 using extensions::Extension;
752 using extensions::Manifest;
753 using extensions::mojom::APIPermissionID;
754 #endif
755
756 #if BUILDFLAG(ENABLE_PLUGINS)
757 using plugins::ChromeContentBrowserClientPluginsPart;
758 #endif
759
760 namespace {
761
762 #if BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) && \
763     !defined(ADDRESS_SANITIZER)
764 // Enables pre-launch Code Integrity Guard (CIG) for Chrome network service
765 // process, when running on Windows 10 1511 and above. This has no effect if
766 // NetworkServiceSandbox feature is disabled. See
767 // https://blogs.windows.com/blog/tag/code-integrity-guard/.
768 BASE_FEATURE(kNetworkServiceCodeIntegrity,
769              "NetworkServiceCodeIntegrity",
770              base::FEATURE_DISABLED_BY_DEFAULT);
771
772 #endif  // BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) &&
773         // !defined(ADDRESS_SANITIZER)
774
775 #if BUILDFLAG(IS_ANDROID)
776 // Kill switch that allows falling back to the legacy behavior on Android when
777 // it comes to site isolation for Gaia's origin (|GaiaUrls::gaia_origin()|).
778 BASE_FEATURE(kAllowGaiaOriginIsolationOnAndroid,
779              "AllowGaiaOriginIsolationOnAndroid",
780              base::FEATURE_ENABLED_BY_DEFAULT);
781
782 BASE_FEATURE(kPrivateNetworkAccessRestrictionsForAutomotive,
783              "PrivateNetworkAccessRestrictionsForAutomotive",
784              base::FEATURE_ENABLED_BY_DEFAULT);
785 #endif  // BUILDFLAG(IS_ANDROID)
786
787 // A small ChromeBrowserMainExtraParts that invokes a callback when threads are
788 // ready. Used to initialize ChromeContentBrowserClient data that needs the UI
789 // thread.
790 class ChromeBrowserMainExtraPartsThreadNotifier final
791     : public ChromeBrowserMainExtraParts {
792  public:
793   explicit ChromeBrowserMainExtraPartsThreadNotifier(
794       base::OnceClosure threads_ready_closure)
795       : threads_ready_closure_(std::move(threads_ready_closure)) {}
796
797   // ChromeBrowserMainExtraParts:
798   void PostCreateThreads() final { std::move(threads_ready_closure_).Run(); }
799
800  private:
801   base::OnceClosure threads_ready_closure_;
802 };
803
804 // Wrapper for SSLErrorHandler::HandleSSLError() that supplies //chrome-level
805 // parameters.
806 void HandleSSLErrorWrapper(
807     content::WebContents* web_contents,
808     int cert_error,
809     const net::SSLInfo& ssl_info,
810     const GURL& request_url,
811     std::unique_ptr<SSLCertReporter> ssl_cert_reporter,
812     SSLErrorHandler::BlockingPageReadyCallback blocking_page_ready_callback) {
813   DCHECK(request_url.SchemeIsCryptographic());
814
815   Profile* profile =
816       Profile::FromBrowserContext(web_contents->GetBrowserContext());
817   // Profile should always outlive a WebContents
818   DCHECK(profile);
819
820   captive_portal::CaptivePortalService* captive_portal_service = nullptr;
821
822 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
823   captive_portal_service = CaptivePortalServiceFactory::GetForProfile(profile);
824 #endif
825
826   const bool is_ssl_error_override_allowed_for_origin =
827       policy::IsOriginInAllowlist(request_url, profile->GetPrefs(),
828                                   prefs::kSSLErrorOverrideAllowedForOrigins,
829                                   prefs::kSSLErrorOverrideAllowed);
830
831   SSLErrorHandler::HandleSSLError(
832       web_contents, cert_error, ssl_info, request_url,
833       std::move(ssl_cert_reporter), std::move(blocking_page_ready_callback),
834       g_browser_process->network_time_tracker(), captive_portal_service,
835       std::make_unique<ChromeSecurityBlockingPageFactory>(),
836       is_ssl_error_override_allowed_for_origin);
837 }
838
839 enum AppLoadedInTabSource {
840   // A platform app page tried to load one of its own URLs in a tab.
841   APP_LOADED_IN_TAB_SOURCE_APP = 0,
842
843   // A platform app background page tried to load one of its own URLs in a tab.
844   APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE,
845
846   // An extension or app tried to load a resource of a different platform app in
847   // a tab.
848   APP_LOADED_IN_TAB_SOURCE_OTHER_EXTENSION,
849
850   // A non-app and non-extension page tried to load a platform app in a tab.
851   APP_LOADED_IN_TAB_SOURCE_OTHER,
852
853   APP_LOADED_IN_TAB_SOURCE_MAX
854 };
855
856 // Cached version of the locale so we can return the locale on the I/O
857 // thread.
858 std::string& GetIOThreadApplicationLocale() {
859   static base::NoDestructor<std::string> s;
860   return *s;
861 }
862
863 // Returns a copy of the given url with its host set to given host and path set
864 // to given path. Other parts of the url will be the same.
865 GURL ReplaceURLHostAndPath(const GURL& url,
866                            const std::string& host,
867                            const std::string& path) {
868   GURL::Replacements replacements;
869   replacements.SetHostStr(host);
870   replacements.SetPathStr(path);
871   return url.ReplaceComponents(replacements);
872 }
873
874 // Handles the rewriting of the new tab page URL based on group policy.
875 bool HandleNewTabPageLocationOverride(
876     GURL* url,
877     content::BrowserContext* browser_context) {
878   if (!url->SchemeIs(content::kChromeUIScheme) ||
879       url->host() != chrome::kChromeUINewTabHost) {
880     return false;
881   }
882
883   Profile* profile = Profile::FromBrowserContext(browser_context);
884
885   // Don't change the URL when incognito mode.
886   if (profile->IsOffTheRecord())
887     return false;
888
889   std::string ntp_location =
890       profile->GetPrefs()->GetString(prefs::kNewTabPageLocationOverride);
891   if (ntp_location.empty())
892     return false;
893   url::Component scheme;
894   if (!url::ExtractScheme(ntp_location.data(),
895                           static_cast<int>(ntp_location.length()), &scheme)) {
896     ntp_location = base::StrCat(
897         {url::kHttpsScheme, url::kStandardSchemeSeparator, ntp_location});
898   }
899
900   *url = GURL(ntp_location);
901   return true;
902 }
903
904 #if !BUILDFLAG(IS_ANDROID)
905 bool IsFileOrDirectoryPickerWithoutGestureAllowed(
906     content::WebContents* contents) {
907   if (!contents) {
908     return true;
909   }
910
911   Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
912   if (!profile) {
913     return true;
914   }
915
916   PrefService* prefs = profile->GetPrefs();
917   if (!prefs) {
918     return true;
919   }
920
921   return !policy::IsOriginInAllowlist(
922       contents->GetURL(), prefs,
923       prefs::kFileOrDirectoryPickerWithoutGestureAllowedForOrigins);
924 }
925
926 // Check if autoplay is allowed by policy configuration.
927 bool IsAutoplayAllowedByPolicy(content::WebContents* contents,
928                                PrefService* prefs) {
929   if (!contents) {
930     return false;
931   }
932
933   return policy::IsOriginInAllowlist(contents->GetURL(), prefs,
934                                      prefs::kAutoplayAllowlist,
935                                      prefs::kAutoplayAllowed);
936 }
937 #endif  // !BUILDFLAG(IS_ANDROID)
938
939 blink::mojom::AutoplayPolicy GetAutoplayPolicyForWebContents(
940     WebContents* web_contents) {
941   const base::CommandLine& command_line =
942       *base::CommandLine::ForCurrentProcess();
943
944   std::string autoplay_policy = media::GetEffectiveAutoplayPolicy(command_line);
945   auto result = blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired;
946
947   if (autoplay_policy == switches::autoplay::kNoUserGestureRequiredPolicy) {
948     result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
949   } else if (autoplay_policy ==
950              switches::autoplay::kUserGestureRequiredPolicy) {
951     result = blink::mojom::AutoplayPolicy::kUserGestureRequired;
952   } else if (autoplay_policy ==
953              switches::autoplay::kDocumentUserActivationRequiredPolicy) {
954     result = blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired;
955   } else {
956     NOTREACHED();
957   }
958
959 #if !BUILDFLAG(IS_ANDROID)
960   Profile* profile =
961       Profile::FromBrowserContext(web_contents->GetBrowserContext());
962   PrefService* prefs = profile->GetPrefs();
963
964   // Override autoplay policy used in internal switch in case of enabling
965   // features such as policy, allowlisting or disabling from settings.
966   if (IsAutoplayAllowedByPolicy(web_contents, prefs)) {
967     result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
968   } else if (base::FeatureList::IsEnabled(media::kAutoplayDisableSettings) &&
969              result == blink::mojom::AutoplayPolicy::
970                            kDocumentUserActivationRequired) {
971     result = UnifiedAutoplayConfig::ShouldBlockAutoplay(profile)
972                  ? blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired
973                  : blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
974   } else if (web_contents->GetPrimaryMainFrame()->IsFeatureEnabled(
975                  blink::mojom::PermissionsPolicyFeature::kAutoplay) &&
976              IsAutoplayAllowedByPolicy(web_contents->GetOuterWebContents(),
977                                        prefs)) {
978     // If the domain policy allows autoplay and has delegated that to an iframe,
979     // allow autoplay within the iframe. Only allow a nesting of single depth.
980     result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired;
981   }
982 #endif  // !BUILDFLAG(IS_ANDROID)
983   return result;
984 }
985
986 #if BUILDFLAG(IS_ANDROID)
987 int GetCrashSignalFD(const base::CommandLine& command_line) {
988   return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
989 }
990 #elif BUILDFLAG(IS_CHROMEOS)
991 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
992     const std::string& process_type) {
993   base::FilePath dumps_path;
994   base::PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
995   {
996     ANNOTATE_SCOPED_MEMORY_LEAK;
997     bool upload = !getenv(env_vars::kHeadless);
998     breakpad::CrashHandlerHostLinux* crash_handler =
999         new breakpad::CrashHandlerHostLinux(process_type, dumps_path, upload);
1000     crash_handler->StartUploaderThread();
1001     return crash_handler;
1002   }
1003 }
1004
1005 int GetCrashSignalFD(const base::CommandLine& command_line) {
1006   if (crash_reporter::IsCrashpadEnabled()) {
1007     int fd;
1008     pid_t pid;
1009     return crash_reporter::GetHandlerSocket(&fd, &pid) ? fd : -1;
1010   }
1011
1012   // Extensions have the same process type as renderers.
1013   if (command_line.HasSwitch(extensions::switches::kExtensionProcess)) {
1014     static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
1015     if (!crash_handler)
1016       crash_handler = CreateCrashHandlerHost("extension");
1017     return crash_handler->GetDeathSignalSocket();
1018   }
1019
1020   std::string process_type =
1021       command_line.GetSwitchValueASCII(switches::kProcessType);
1022
1023   if (process_type == switches::kRendererProcess) {
1024     static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
1025     if (!crash_handler)
1026       crash_handler = CreateCrashHandlerHost(process_type);
1027     return crash_handler->GetDeathSignalSocket();
1028   }
1029
1030   if (process_type == switches::kPpapiPluginProcess) {
1031     static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
1032     if (!crash_handler)
1033       crash_handler = CreateCrashHandlerHost(process_type);
1034     return crash_handler->GetDeathSignalSocket();
1035   }
1036
1037   if (process_type == switches::kGpuProcess) {
1038     static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
1039     if (!crash_handler)
1040       crash_handler = CreateCrashHandlerHost(process_type);
1041     return crash_handler->GetDeathSignalSocket();
1042   }
1043
1044   if (process_type == switches::kUtilityProcess) {
1045     static breakpad::CrashHandlerHostLinux* crash_handler = nullptr;
1046     if (!crash_handler)
1047       crash_handler = CreateCrashHandlerHost(process_type);
1048     return crash_handler->GetDeathSignalSocket();
1049   }
1050
1051   return -1;
1052 }
1053 #elif BUILDFLAG(IS_LINUX)
1054 int GetCrashSignalFD(const base::CommandLine& command_line) {
1055   int fd;
1056   return crash_reporter::GetHandlerSocket(&fd, nullptr) ? fd : -1;
1057 }
1058 #endif  // BUILDFLAG(IS_ANDROID)
1059
1060 void SetApplicationLocaleOnIOThread(const std::string& locale) {
1061   DCHECK_CURRENTLY_ON(BrowserThread::IO);
1062   GetIOThreadApplicationLocale() = locale;
1063 }
1064
1065 // An implementation of the SSLCertReporter interface used by
1066 // SSLErrorHandler. Uses CertificateReportingService to send reports. The
1067 // service handles queueing and re-sending of failed reports. Each certificate
1068 // error creates a new instance of this class.
1069 class CertificateReportingServiceCertReporter : public SSLCertReporter {
1070  public:
1071   explicit CertificateReportingServiceCertReporter(
1072       content::WebContents* web_contents)
1073       : service_(CertificateReportingServiceFactory::GetForBrowserContext(
1074             web_contents->GetBrowserContext())) {}
1075
1076   CertificateReportingServiceCertReporter(
1077       const CertificateReportingServiceCertReporter&) = delete;
1078   CertificateReportingServiceCertReporter& operator=(
1079       const CertificateReportingServiceCertReporter&) = delete;
1080
1081   ~CertificateReportingServiceCertReporter() override {}
1082
1083   // SSLCertReporter implementation
1084   void ReportInvalidCertificateChain(
1085       const std::string& serialized_report) override {
1086     service_->Send(serialized_report);
1087   }
1088
1089  private:
1090   raw_ptr<CertificateReportingService> service_;
1091 };
1092
1093 #if BUILDFLAG(ENABLE_EXTENSIONS)
1094
1095 AppLoadedInTabSource ClassifyAppLoadedInTabSource(
1096     const GURL& opener_url,
1097     const extensions::Extension* target_platform_app) {
1098   if (!opener_url.SchemeIs(extensions::kExtensionScheme)) {
1099     // The forbidden app URL was being opened by a non-extension page (e.g.
1100     // http).
1101     return APP_LOADED_IN_TAB_SOURCE_OTHER;
1102   }
1103
1104   if (opener_url.host_piece() != target_platform_app->id()) {
1105     // The forbidden app URL was being opened by a different app or extension.
1106     return APP_LOADED_IN_TAB_SOURCE_OTHER_EXTENSION;
1107   }
1108
1109   // This platform app was trying to window.open() one of its own URLs.
1110   if (opener_url ==
1111       extensions::BackgroundInfo::GetBackgroundURL(target_platform_app)) {
1112     // Source was the background page.
1113     return APP_LOADED_IN_TAB_SOURCE_BACKGROUND_PAGE;
1114   }
1115
1116   // Source was a different page inside the app.
1117   return APP_LOADED_IN_TAB_SOURCE_APP;
1118 }
1119
1120 // Returns true if there is is an extension matching `url` in
1121 // `render_process_id` with `permission`.
1122 //
1123 // GetExtensionOrAppByURL requires a full URL in order to match with a hosted
1124 // app, even though normal extensions just use the host.
1125 bool URLHasExtensionPermission(extensions::ProcessMap* process_map,
1126                                extensions::ExtensionRegistry* registry,
1127                                const GURL& url,
1128                                int render_process_id,
1129                                APIPermissionID permission) {
1130   // Includes web URLs that are part of an extension's web extent.
1131   const Extension* extension =
1132       registry->enabled_extensions().GetExtensionOrAppByURL(url);
1133   return extension &&
1134          extension->permissions_data()->HasAPIPermission(permission) &&
1135          process_map->Contains(extension->id(), render_process_id);
1136 }
1137
1138 // Returns true if |extension_id| is allowed to run as an Isolated Context,
1139 // giving it access to additional APIs.
1140 bool IsExtensionIdAllowedToUseIsolatedContext(base::StringPiece extension_id) {
1141   static constexpr auto kAllowedIsolatedContextExtensionIds =
1142       base::MakeFixedFlatSet<base::StringPiece>({
1143           "algkcnfjnajfhgimadimbjhmpaeohhln",  // Secure Shell Extension (dev)
1144           "iodihamcpbpeioajjeobimgagajmlibd",  // Secure Shell Extension
1145                                                // (stable)
1146           // Extension IDs used in tests.
1147           "bbobefdodiifgmhhdijgpelmkdaebfpn",  // Controlled Frame Service
1148                                                // Worker Test
1149       });
1150   return base::Contains(kAllowedIsolatedContextExtensionIds, extension_id);
1151 }
1152
1153 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
1154
1155 mojo::PendingRemote<prerender::mojom::PrerenderCanceler> GetPrerenderCanceler(
1156     base::OnceCallback<content::WebContents*()> wc_getter) {
1157   mojo::PendingRemote<prerender::mojom::PrerenderCanceler> canceler;
1158   prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
1159       std::move(wc_getter).Run())
1160       ->AddPrerenderCancelerReceiver(canceler.InitWithNewPipeAndPassReceiver());
1161   return canceler;
1162 }
1163
1164 bool ShouldHonorPolicies() {
1165 #if BUILDFLAG(IS_WIN)
1166   return policy::ManagementServiceFactory::GetForPlatform()
1167              ->GetManagementAuthorityTrustworthiness() >=
1168          policy::ManagementAuthorityTrustworthiness::TRUSTED;
1169 #else
1170   return true;
1171 #endif
1172 }
1173
1174 // Used by Enterprise policy. Disable blocking of navigations toward external
1175 // applications from a sandboxed iframe.
1176 // https://chromestatus.com/feature/5680742077038592
1177 const char kDisableSandboxExternalProtocolSwitch[] =
1178     "disable-sandbox-external-protocols";
1179
1180 void LaunchURL(
1181     base::WeakPtr<ChromeContentBrowserClient> client,
1182     const GURL& url,
1183     content::WebContents::Getter web_contents_getter,
1184     ui::PageTransition page_transition,
1185     bool is_primary_main_frame,
1186     bool is_in_fenced_frame_tree,
1187     network::mojom::WebSandboxFlags sandbox_flags,
1188     bool has_user_gesture,
1189     const absl::optional<url::Origin>& initiating_origin,
1190     content::WeakDocumentPtr initiator_document
1191 #if BUILDFLAG(IS_ANDROID)
1192     ,
1193     mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory
1194 #endif
1195 ) {
1196   // If there is no longer a WebContents, the request may have raced with tab
1197   // closing. Don't fire the external request. (It may have been a prerender.)
1198   content::WebContents* web_contents = web_contents_getter.Run();
1199   if (!web_contents)
1200     return;
1201
1202   // Do not launch external requests attached to unswapped no-state prefetchers.
1203   prerender::NoStatePrefetchContents* no_state_prefetch_contents =
1204       prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
1205           web_contents);
1206   if (no_state_prefetch_contents) {
1207     no_state_prefetch_contents->Destroy(
1208         prerender::FINAL_STATUS_UNSUPPORTED_SCHEME);
1209     return;
1210   }
1211
1212   // Do not launch external requests for schemes that have a handler registered.
1213   custom_handlers::ProtocolHandlerRegistry* protocol_handler_registry =
1214       ProtocolHandlerRegistryFactory::GetForBrowserContext(
1215           web_contents->GetBrowserContext());
1216   if (protocol_handler_registry &&
1217       protocol_handler_registry->IsHandledProtocol(url.scheme()))
1218     return;
1219
1220   // Sandbox flags
1221   // =============
1222   //
1223   // Navigations to external protocol in iframe can be seen as "top-level"
1224   // navigations somehow, because they cause the user to switch from Chrome's
1225   // page toward a different application.
1226   //
1227   // Internally in Chrome, they are seen as aborted iframe navigation, so the
1228   // regular sandbox logic do not really apply.
1229   //
1230   // This block adds an extra logic, gating external protocol in iframes to have
1231   // one of:
1232   // - 'allow-top-navigation'
1233   // - 'allow-top-navigation-to-custom-protocols'
1234   // - 'allow-top-navigation-by-user-navigation' + user-activation
1235   // - 'allow-popups'
1236   //
1237   // See https://crbug.com/1148777
1238   if (!is_primary_main_frame) {
1239     using SandboxFlags = network::mojom::WebSandboxFlags;
1240     auto allow = [&](SandboxFlags flag) {
1241       return (sandbox_flags & flag) == SandboxFlags::kNone;
1242     };
1243     bool allowed = (allow(SandboxFlags::kTopNavigationToCustomProtocols)) ||
1244                    (allow(SandboxFlags::kTopNavigationByUserActivation) &&
1245                     has_user_gesture);
1246
1247     if (!allowed) {
1248       content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame();
1249       if (client) {
1250         client->LogWebFeatureForCurrentPage(
1251             rfh, blink::mojom::WebFeature::kExternalProtocolBlockedBySandbox);
1252       }
1253
1254       if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1255               kDisableSandboxExternalProtocolSwitch)) {
1256         if (base::FeatureList::IsEnabled(
1257                 features::kSandboxExternalProtocolBlocked)) {
1258           rfh->AddMessageToConsole(
1259               blink::mojom::ConsoleMessageLevel::kError,
1260               "Navigation to external protocol blocked by sandbox, because it "
1261               "doesn't contain any of: "
1262               "'allow-top-navigation-to-custom-protocols', "
1263               "'allow-top-navigation-by-user-activation', "
1264               "'allow-top-navigation', or "
1265               "'allow-popups'. See "
1266               "https://chromestatus.com/feature/5680742077038592 and "
1267               "https://chromeenterprise.google/policies/"
1268               "#SandboxExternalProtocolBlocked");
1269           return;
1270         }
1271
1272         if (base::FeatureList::IsEnabled(
1273                 features::kSandboxExternalProtocolBlockedWarning)) {
1274           rfh->AddMessageToConsole(
1275               blink::mojom::ConsoleMessageLevel::kError,
1276               "After Chrome M103, navigation toward external protocol "
1277               "will be blocked by sandbox, if it doesn't contain any of:"
1278               "'allow-top-navigation-to-custom-protocols', "
1279               "'allow-top-navigation-by-user-activation', "
1280               "'allow-top-navigation', or "
1281               "'allow-popups'. See "
1282               "https://chromestatus.com/feature/5680742077038592 and "
1283               "https://chromeenterprise.google/policies/"
1284               "#SandboxExternalProtocolBlocked");
1285         }
1286       }
1287     }
1288   }
1289
1290   bool is_allowlisted = false;
1291   PolicyBlocklistService* service =
1292       PolicyBlocklistFactory::GetForBrowserContext(
1293           web_contents->GetBrowserContext());
1294   if (ShouldHonorPolicies() && service) {
1295     const policy::URLBlocklist::URLBlocklistState url_state =
1296         service->GetURLBlocklistState(url);
1297     is_allowlisted =
1298         url_state == policy::URLBlocklist::URLBlocklistState::URL_IN_ALLOWLIST;
1299   }
1300
1301   // If the URL is in allowlist, we launch it without asking the user and
1302   // without any additional security checks. Since the URL is allowlisted,
1303   // we assume it can be executed.
1304   if (is_allowlisted) {
1305     ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(
1306         url, web_contents, std::move(initiator_document));
1307   } else {
1308     ExternalProtocolHandler::LaunchUrl(
1309         url, std::move(web_contents_getter), page_transition, has_user_gesture,
1310         is_in_fenced_frame_tree, initiating_origin,
1311         std::move(initiator_document)
1312 #if BUILDFLAG(IS_ANDROID)
1313             ,
1314         out_factory
1315 #endif
1316     );
1317   }
1318 }
1319
1320 void MaybeAppendSecureOriginsAllowlistSwitch(base::CommandLine* cmdline) {
1321   // |allowlist| combines pref/policy + cmdline switch in the browser process.
1322   // For renderer and utility (e.g. NetworkService) processes the switch is the
1323   // only available source, so below the combined (pref/policy + cmdline)
1324   // allowlist of secure origins is injected into |cmdline| for these other
1325   // processes.
1326   std::vector<std::string> allowlist =
1327       network::SecureOriginAllowlist::GetInstance().GetCurrentAllowlist();
1328   if (!allowlist.empty()) {
1329     cmdline->AppendSwitchASCII(
1330         network::switches::kUnsafelyTreatInsecureOriginAsSecure,
1331         base::JoinString(allowlist, ","));
1332   }
1333 }
1334
1335 #if BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) && \
1336     !defined(ADDRESS_SANITIZER)
1337 // Returns the full path to |module_name|. Both dev builds (where |module_name|
1338 // is in the current executable's directory) and proper installs (where
1339 // |module_name| is in a versioned sub-directory of the current executable's
1340 // directory) are supported. The identified file is not guaranteed to exist.
1341 base::FilePath GetModulePath(base::WStringPiece module_name) {
1342   base::FilePath exe_dir;
1343   const bool has_path = base::PathService::Get(base::DIR_EXE, &exe_dir);
1344   DCHECK(has_path);
1345
1346   // Look for the module in a versioned sub-directory of the current
1347   // executable's directory and return the path if it can be read. This is the
1348   // expected location of modules for proper installs.
1349   const base::FilePath module_path =
1350       exe_dir.AppendASCII(chrome::kChromeVersion).Append(module_name);
1351   if (base::PathExists(module_path))
1352     return module_path;
1353
1354   // Otherwise, return the path to the module in the current executable's
1355   // directory. This is the expected location of modules for dev builds.
1356   return exe_dir.Append(module_name);
1357 }
1358 #endif  // BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) &&
1359         // !defined(ADDRESS_SANITIZER)
1360
1361 void MaybeAddThrottle(
1362     std::unique_ptr<content::NavigationThrottle> maybe_throttle,
1363     std::vector<std::unique_ptr<content::NavigationThrottle>>* throttles) {
1364   if (maybe_throttle)
1365     throttles->push_back(std::move(maybe_throttle));
1366 }
1367
1368 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
1369 void MaybeAddCondition(
1370     std::unique_ptr<content::CommitDeferringCondition> maybe_condition,
1371     std::vector<std::unique_ptr<content::CommitDeferringCondition>>*
1372         conditions) {
1373   if (maybe_condition)
1374     conditions->push_back(std::move(maybe_condition));
1375 }
1376 #endif
1377
1378 void MaybeAddThrottles(
1379     std::vector<std::unique_ptr<content::NavigationThrottle>> additional,
1380     std::vector<std::unique_ptr<content::NavigationThrottle>>* combined) {
1381   combined->insert(combined->end(), std::make_move_iterator(additional.begin()),
1382                    std::make_move_iterator(additional.end()));
1383 }
1384
1385 // Returns whether |web_contents| is within a hosted app.
1386 bool IsInHostedApp(WebContents* web_contents) {
1387 #if BUILDFLAG(ENABLE_EXTENSIONS)
1388   Browser* browser = chrome::FindBrowserWithTab(web_contents);
1389   return web_app::AppBrowserController::IsWebApp(browser);
1390 #else
1391   return false;
1392 #endif
1393 }
1394
1395 bool IsErrorPageAutoReloadEnabled() {
1396   const base::CommandLine& command_line =
1397       *base::CommandLine::ForCurrentProcess();
1398   if (command_line.HasSwitch(switches::kEnableAutomation))
1399     return false;
1400   if (command_line.HasSwitch(embedder_support::kEnableAutoReload))
1401     return true;
1402   if (command_line.HasSwitch(embedder_support::kDisableAutoReload))
1403     return false;
1404   return true;
1405 }
1406
1407 bool IsTopChromeWebUIURL(const GURL& url) {
1408   return url.SchemeIs(content::kChromeUIScheme) &&
1409          base::EndsWith(url.host_piece(), chrome::kChromeUITopChromeDomain);
1410 }
1411
1412 // Checks whether a render process hosting a top chrome page exists.
1413 bool IsTopChromeRendererPresent(Profile* profile) {
1414   for (auto rph_iterator = content::RenderProcessHost::AllHostsIterator();
1415        !rph_iterator.IsAtEnd(); rph_iterator.Advance()) {
1416     content::RenderProcessHost* rph = rph_iterator.GetCurrentValue();
1417
1418     // Consider only valid RenderProcessHosts that belong to the current
1419     // profile.
1420     if (rph->IsInitializedAndNotDead() &&
1421         profile->IsSameOrParent(
1422             Profile::FromBrowserContext(rph->GetBrowserContext()))) {
1423       bool is_top_chrome_renderer_present = false;
1424       rph->ForEachRenderFrameHost(base::BindRepeating(
1425           [](bool* is_top_chrome_renderer_present,
1426              content::RenderFrameHost* rfh) {
1427             *is_top_chrome_renderer_present |=
1428                 IsTopChromeWebUIURL(rfh->GetSiteInstance()->GetSiteURL());
1429           },
1430           &is_top_chrome_renderer_present));
1431
1432       // Return true if a rph hosting a top chrome WebUI has been found.
1433       if (is_top_chrome_renderer_present)
1434         return true;
1435     }
1436   }
1437   return false;
1438 }
1439
1440 // Return false if a top chrome renderer exists. This is done to ensure the
1441 // spare renderer is not taken and the existing top chrome renderer is
1442 // considered instead.
1443 // TODO(crbug.com/1291351, tluk): This is needed since spare renderers are
1444 // considered before existing processes for reuse. This can be simplified by
1445 // migrating to SiteInstanceGroups once the project has landed.
1446 bool ShouldUseSpareRenderProcessHostForTopChromePage(Profile* profile) {
1447   return base::FeatureList::IsEnabled(
1448              features::kTopChromeWebUIUsesSpareRenderer) &&
1449          !IsTopChromeRendererPresent(profile);
1450 }
1451
1452 #if BUILDFLAG(FULL_SAFE_BROWSING)
1453
1454 void HandleExpandedPaths(
1455     std::unique_ptr<enterprise_connectors::FilesScanData> fsd,
1456     base::WeakPtr<content::WebContents> web_contents,
1457     enterprise_connectors::ContentAnalysisDelegate::Data dialog_data,
1458     enterprise_connectors::AnalysisConnector connector,
1459     std::vector<base::FilePath> paths,
1460     ChromeContentBrowserClient::IsClipboardPasteContentAllowedCallback
1461         callback) {
1462   if (!web_contents)
1463     return;
1464
1465   dialog_data.paths = fsd->expanded_paths();
1466   enterprise_connectors::ContentAnalysisDelegate::CreateForWebContents(
1467       web_contents.get(), std::move(dialog_data),
1468       base::BindOnce(
1469           [](std::unique_ptr<enterprise_connectors::FilesScanData> fsd,
1470              std::vector<base::FilePath> paths,
1471              ChromeContentBrowserClient::IsClipboardPasteContentAllowedCallback
1472                  callback,
1473              const enterprise_connectors::ContentAnalysisDelegate::Data& data,
1474              enterprise_connectors::ContentAnalysisDelegate::Result& result) {
1475             absl::optional<ChromeContentBrowserClient::ClipboardPasteData>
1476                 clipboard_paste_data;
1477             auto blocked = fsd->IndexesToBlock(result.paths_results);
1478             if (blocked.size() != paths.size()) {
1479               // Build the data string of the allowed paths.
1480               std::vector<std::string> string_paths;
1481               string_paths.reserve(paths.size());
1482               for (size_t i = 0; i < paths.size(); ++i) {
1483                 if (base::Contains(blocked, i)) {
1484                   result.paths_results[i] = false;
1485                 } else {
1486                   string_paths.push_back(paths[i].AsUTF8Unsafe());
1487                   DCHECK(result.paths_results[i]);
1488                 }
1489               }
1490               clipboard_paste_data =
1491                   ChromeContentBrowserClient::ClipboardPasteData(
1492                       std::string(), std::string(), std::move(string_paths));
1493             }
1494             std::move(callback).Run(std::move(clipboard_paste_data));
1495           },
1496           std::move(fsd), std::move(paths), std::move(callback)),
1497       safe_browsing::DeepScanAccessPoint::PASTE);
1498 }
1499
1500 void HandleStringData(
1501     content::WebContents* web_contents,
1502     enterprise_connectors::ContentAnalysisDelegate::Data dialog_data,
1503     enterprise_connectors::AnalysisConnector connector,
1504     ChromeContentBrowserClient::IsClipboardPasteContentAllowedCallback
1505         callback) {
1506   enterprise_connectors::ContentAnalysisDelegate::CreateForWebContents(
1507       web_contents, std::move(dialog_data),
1508       base::BindOnce(
1509           [](ChromeContentBrowserClient::IsClipboardPasteContentAllowedCallback
1510                  callback,
1511              const enterprise_connectors::ContentAnalysisDelegate::Data& data,
1512              enterprise_connectors::ContentAnalysisDelegate::Result& result) {
1513             absl::optional<ChromeContentBrowserClient::ClipboardPasteData>
1514                 clipboard_paste_data;
1515             clipboard_paste_data =
1516                 ChromeContentBrowserClient::ClipboardPasteData(
1517                     data.text[0], std::string(), {});
1518             std::move(callback).Run(result.text_results[0]
1519                                         ? std::move(clipboard_paste_data)
1520                                         : absl::nullopt);
1521           },
1522           std::move(callback)),
1523       safe_browsing::DeepScanAccessPoint::PASTE);
1524 }
1525
1526 #endif
1527
1528 std::unique_ptr<blocked_content::PopupNavigationDelegate>
1529 CreatePopupNavigationDelegate(NavigateParams params) {
1530   return std::make_unique<ChromePopupNavigationDelegate>(std::move(params));
1531 }
1532
1533 ChromeContentBrowserClient::PopupNavigationDelegateFactory
1534     g_popup_navigation_delegate_factory = &CreatePopupNavigationDelegate;
1535
1536 }  // namespace
1537
1538 // static
1539 ChromeContentBrowserClient::PopupNavigationDelegateFactory&
1540 ChromeContentBrowserClient::GetPopupNavigationDelegateFactoryForTesting() {
1541   return g_popup_navigation_delegate_factory;
1542 }
1543
1544 ChromeContentBrowserClient::ChromeContentBrowserClient() {
1545 #if BUILDFLAG(ENABLE_PLUGINS)
1546   extra_parts_.push_back(
1547       std::make_unique<ChromeContentBrowserClientPluginsPart>());
1548 #endif
1549
1550 #if BUILDFLAG(IS_CHROMEOS)
1551   extra_parts_.push_back(
1552       std::make_unique<ChromeContentBrowserClientTabletModePart>());
1553 #endif  // BUILDFLAG(IS_CHROMEOS)
1554
1555 #if !BUILDFLAG(IS_ANDROID)
1556   extra_parts_.push_back(
1557       std::make_unique<ChromeContentBrowserClientWebUiPart>());
1558 #endif
1559
1560 #if BUILDFLAG(ENABLE_EXTENSIONS)
1561   extra_parts_.push_back(
1562       std::make_unique<ChromeContentBrowserClientExtensionsPart>());
1563 #endif
1564
1565   extra_parts_.push_back(
1566       std::make_unique<ChromeContentBrowserClientPerformanceManagerPart>());
1567 }
1568
1569 ChromeContentBrowserClient::~ChromeContentBrowserClient() {
1570   // std::vector<> does not guarantee any specific destruction order, so
1571   // explicitly destroy elements in the reverse order per header comment.
1572   while (!extra_parts_.empty()) {
1573     extra_parts_.pop_back();
1574   }
1575 }
1576
1577 // static
1578 void ChromeContentBrowserClient::RegisterLocalStatePrefs(
1579     PrefRegistrySimple* registry) {
1580   registry->RegisterFilePathPref(prefs::kDiskCacheDir, base::FilePath());
1581   registry->RegisterIntegerPref(prefs::kDiskCacheSize, 0);
1582   registry->RegisterStringPref(prefs::kIsolateOrigins, std::string());
1583   registry->RegisterBooleanPref(prefs::kSitePerProcess, false);
1584   registry->RegisterBooleanPref(prefs::kTabFreezingEnabled, true);
1585   registry->RegisterIntegerPref(prefs::kSCTAuditingHashdanceReportCount, 0);
1586   registry->RegisterBooleanPref(
1587       prefs::kThrottleNonVisibleCrossOriginIframesAllowed, true);
1588   registry->RegisterBooleanPref(prefs::kNewBaseUrlInheritanceBehaviorAllowed,
1589                                 true);
1590   registry->RegisterBooleanPref(prefs::kNativeClientForceAllowed, false);
1591   registry->RegisterBooleanPref(
1592       policy::policy_prefs::kPPAPISharedImagesForVideoDecoderAllowed, true);
1593 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
1594   registry->RegisterBooleanPref(prefs::kOutOfProcessSystemDnsResolutionEnabled,
1595                                 true);
1596 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
1597 }
1598
1599 // static
1600 void ChromeContentBrowserClient::RegisterProfilePrefs(
1601     user_prefs::PrefRegistrySyncable* registry) {
1602   registry->RegisterBooleanPref(prefs::kDisable3DAPIs, false);
1603   registry->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true);
1604   // Register user prefs for mapping SitePerProcess and IsolateOrigins in
1605   // user policy in addition to the same named ones in Local State (which are
1606   // used for mapping the command-line flags).
1607   registry->RegisterStringPref(prefs::kIsolateOrigins, std::string());
1608   registry->RegisterBooleanPref(prefs::kSitePerProcess, false);
1609   registry->RegisterListPref(
1610       site_isolation::prefs::kUserTriggeredIsolatedOrigins);
1611   registry->RegisterDictionaryPref(
1612       site_isolation::prefs::kWebTriggeredIsolatedOrigins);
1613   registry->RegisterDictionaryPref(
1614       prefs::kDevToolsBackgroundServicesExpirationDict);
1615   registry->RegisterBooleanPref(prefs::kSignedHTTPExchangeEnabled, true);
1616 #if !BUILDFLAG(IS_ANDROID)
1617   registry->RegisterBooleanPref(prefs::kAutoplayAllowed, false);
1618   registry->RegisterListPref(prefs::kAutoplayAllowlist);
1619   registry->RegisterListPref(
1620       prefs::kScreenCaptureWithoutGestureAllowedForOrigins);
1621   registry->RegisterListPref(
1622       prefs::kFileOrDirectoryPickerWithoutGestureAllowedForOrigins);
1623   registry->RegisterIntegerPref(prefs::kFetchKeepaliveDurationOnShutdown, 0);
1624   registry->RegisterBooleanPref(
1625       prefs::kSharedArrayBufferUnrestrictedAccessAllowed, false);
1626 #endif
1627   registry->RegisterBooleanPref(prefs::kSandboxExternalProtocolBlocked, true);
1628   registry->RegisterBooleanPref(prefs::kSSLErrorOverrideAllowed, true);
1629   registry->RegisterListPref(prefs::kSSLErrorOverrideAllowedForOrigins);
1630   registry->RegisterBooleanPref(prefs::kCompressionDictionaryTransportEnabled,
1631                                 true);
1632   registry->RegisterBooleanPref(
1633       prefs::kSuppressDifferentOriginSubframeJSDialogs, true);
1634 #if BUILDFLAG(IS_ANDROID)
1635   registry->RegisterBooleanPref(prefs::kWebXRImmersiveArEnabled, true);
1636 #endif
1637   registry->RegisterBooleanPref(prefs::kPromptOnMultipleMatchingCertificates,
1638                                 false);
1639   registry->RegisterBooleanPref(prefs::kCorsNonWildcardRequestHeadersSupport,
1640                                 true);
1641   registry->RegisterBooleanPref(prefs::kIPv6ReachabilityOverrideEnabled, false);
1642   registry->RegisterDictionaryPref(
1643       enterprise::content::kCopyPreventionSettings);
1644   registry->RegisterIntegerPref(
1645       prefs::kUserAgentReduction,
1646       static_cast<int>(
1647           embedder_support::UserAgentReductionEnterprisePolicyState::kDefault));
1648   registry->RegisterBooleanPref(prefs::kOriginAgentClusterDefaultEnabled, true);
1649   registry->RegisterBooleanPref(
1650       policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed, true);
1651
1652   registry->RegisterBooleanPref(
1653       prefs::kStrictMimetypeCheckForWorkerScriptsEnabled, true);
1654   registry->RegisterBooleanPref(policy::policy_prefs::kFeedbackSurveysEnabled,
1655                                 true);
1656   registry->RegisterBooleanPref(
1657       prefs::kAccessControlAllowMethodsInCORSPreflightSpecConformant, true);
1658
1659   registry->RegisterBooleanPref(
1660       policy::policy_prefs::kOffsetParentNewSpecBehaviorEnabled, true);
1661   registry->RegisterBooleanPref(
1662       policy::policy_prefs::kSendMouseEventsDisabledFormControlsEnabled, true);
1663   registry->RegisterBooleanPref(prefs::kDataUrlInSvgUseEnabled, false);
1664
1665   registry->RegisterBooleanPref(
1666       policy::policy_prefs::kBeforeunloadEventCancelByPreventDefaultEnabled,
1667       true);
1668
1669   registry->RegisterBooleanPref(
1670       policy::policy_prefs::
1671           kAllowBackForwardCacheForCacheControlNoStorePageEnabled,
1672       true);
1673
1674   registry->RegisterBooleanPref(
1675       policy::policy_prefs::kForcePermissionPolicyUnloadDefaultEnabled, false);
1676
1677 #if BUILDFLAG(IS_CHROMEOS)
1678   registry->RegisterListPref(prefs::kMandatoryExtensionsForIncognitoNavigation);
1679 #endif
1680 }
1681
1682 // static
1683 void ChromeContentBrowserClient::SetApplicationLocale(
1684     const std::string& locale) {
1685   // The common case is that this function is called early in Chrome startup
1686   // before any threads are created or registered. When there are no threads,
1687   // we can just set the string without worrying about threadsafety.
1688   if (!BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
1689     GetIOThreadApplicationLocale() = locale;
1690     return;
1691   }
1692
1693   // Otherwise we're being called to change the locale. In this case set it on
1694   // the IO thread.
1695   DCHECK_CURRENTLY_ON(BrowserThread::UI);
1696
1697   content::GetIOThreadTaskRunner({})->PostTask(
1698       FROM_HERE, base::BindOnce(&SetApplicationLocaleOnIOThread, locale));
1699 }
1700
1701 std::unique_ptr<content::BrowserMainParts>
1702 ChromeContentBrowserClient::CreateBrowserMainParts(bool is_integration_test) {
1703   std::unique_ptr<ChromeBrowserMainParts> main_parts;
1704   // Construct the Main browser parts based on the OS type.
1705 #if BUILDFLAG(IS_WIN)
1706   main_parts = std::make_unique<ChromeBrowserMainPartsWin>(is_integration_test,
1707                                                            &startup_data_);
1708 #elif BUILDFLAG(IS_MAC)
1709   main_parts = std::make_unique<ChromeBrowserMainPartsMac>(is_integration_test,
1710                                                            &startup_data_);
1711 #elif BUILDFLAG(IS_CHROMEOS_ASH)
1712   main_parts = std::make_unique<ash::ChromeBrowserMainPartsAsh>(
1713       is_integration_test, &startup_data_);
1714 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
1715   main_parts = std::make_unique<ChromeBrowserMainPartsLacros>(
1716       is_integration_test, &startup_data_);
1717 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
1718   main_parts = std::make_unique<ChromeBrowserMainPartsLinux>(
1719       is_integration_test, &startup_data_);
1720 #elif BUILDFLAG(IS_ANDROID)
1721   main_parts = std::make_unique<ChromeBrowserMainPartsAndroid>(
1722       is_integration_test, &startup_data_);
1723 #elif BUILDFLAG(IS_POSIX)
1724   main_parts = std::make_unique<ChromeBrowserMainPartsPosix>(
1725       is_integration_test, &startup_data_);
1726 #elif BUILDFLAG(IS_FUCHSIA)
1727   main_parts = std::make_unique<ChromeBrowserMainPartsFuchsia>(
1728       is_integration_test, &startup_data_);
1729 #else
1730 #error "Unimplemented platform"
1731 #endif
1732
1733   main_parts->AddParts(
1734       std::make_unique<ChromeBrowserMainExtraPartsThreadNotifier>(
1735           base::BindOnce(&ChromeContentBrowserClient::InitOnUIThread,
1736                          weak_factory_.GetWeakPtr())));
1737
1738   bool add_profiles_extra_parts = true;
1739 #if BUILDFLAG(IS_ANDROID)
1740   if (startup_data_.HasBuiltProfilePrefService())
1741     add_profiles_extra_parts = false;
1742 #endif
1743   if (add_profiles_extra_parts)
1744     chrome::AddProfilesExtraParts(main_parts.get());
1745
1746     // Construct additional browser parts. Stages are called in the order in
1747     // which they are added.
1748 #if defined(TOOLKIT_VIEWS)
1749 #if BUILDFLAG(IS_CHROMEOS_LACROS)
1750   main_parts->AddParts(
1751       std::make_unique<ChromeBrowserMainExtraPartsViewsLacros>());
1752 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
1753 // of lacros-chrome is complete.
1754 #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
1755   main_parts->AddParts(
1756       std::make_unique<ChromeBrowserMainExtraPartsViewsLinux>());
1757 #else
1758   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsViews>());
1759 #endif
1760 #endif
1761
1762 #if BUILDFLAG(IS_MAC)
1763   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsMac>());
1764 #endif
1765
1766 #if BUILDFLAG(IS_CHROMEOS_ASH)
1767   // TODO(jamescook): Combine with `ChromeBrowserMainPartsAsh`.
1768   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsAsh>());
1769 #endif
1770
1771 #if BUILDFLAG(IS_CHROMEOS_LACROS)
1772   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsLacros>());
1773 #endif
1774
1775 #if BUILDFLAG(IS_LINUX)
1776   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsLinux>());
1777 #elif BUILDFLAG(IS_OZONE)
1778   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsOzone>());
1779 #endif
1780
1781   main_parts->AddParts(
1782       std::make_unique<ChromeBrowserMainExtraPartsPerformanceMonitor>());
1783
1784   main_parts->AddParts(
1785       std::make_unique<ChromeBrowserMainExtraPartsPerformanceManager>());
1786
1787   main_parts->AddParts(
1788       std::make_unique<ChromeBrowserMainExtraPartsProfiling>());
1789
1790   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsMemory>());
1791
1792   chrome::AddMetricsExtraParts(main_parts.get());
1793
1794 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
1795   main_parts->AddParts(
1796       std::make_unique<
1797           chrome::enterprise_util::ChromeBrowserMainExtraPartsEnterprise>());
1798 #endif
1799
1800 #if !BUILDFLAG(IS_ANDROID)
1801   main_parts->AddParts(
1802       std::make_unique<headless::ChromeBrowserMainExtraPartsHeadless>());
1803 #endif
1804
1805   // Always add ChromeBrowserMainExtraPartsGpu last to make sure
1806   // GpuDataManager initialization could pick up about:flags settings.
1807   main_parts->AddParts(std::make_unique<ChromeBrowserMainExtraPartsGpu>());
1808
1809   main_parts->AddParts(
1810       std::make_unique<ChromeBrowserMainExtraPartsSegmentationPlatform>());
1811
1812   main_parts->AddParts(
1813       std::make_unique<ChromeBrowserMainExtraPartsOptimizationGuide>());
1814
1815   main_parts->AddParts(
1816       std::make_unique<ChromeBrowserMainExtraPartsNaclDeprecation>());
1817
1818   return main_parts;
1819 }
1820
1821 void ChromeContentBrowserClient::PostAfterStartupTask(
1822     const base::Location& from_here,
1823     const scoped_refptr<base::SequencedTaskRunner>& task_runner,
1824     base::OnceClosure task) {
1825   AfterStartupTaskUtils::PostTask(from_here, task_runner, std::move(task));
1826 }
1827
1828 bool ChromeContentBrowserClient::IsBrowserStartupComplete() {
1829   return AfterStartupTaskUtils::IsBrowserStartupComplete();
1830 }
1831
1832 void ChromeContentBrowserClient::SetBrowserStartupIsCompleteForTesting() {
1833   AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting();
1834 }
1835
1836 bool ChromeContentBrowserClient::IsShuttingDown() {
1837   return browser_shutdown::HasShutdownStarted();
1838 }
1839
1840 content::StoragePartitionConfig
1841 ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
1842     content::BrowserContext* browser_context,
1843     const GURL& site) {
1844   // Default to the browser-wide storage partition and override based on |site|
1845   // below.
1846   content::StoragePartitionConfig default_storage_partition_config =
1847       content::StoragePartitionConfig::CreateDefault(browser_context);
1848
1849   // A non-default storage partition is used in the following situations:
1850   // - To enforce process isolation between a more-trusted content (Chrome Apps,
1851   // Extensions, and Isolated Web Apps) and regular web content.
1852   // - For the <webview> tag, which Chrome Apps, Isolated Web Apps and WebUI use
1853   // to create temporary storage buckets for loading various kinds of web
1854   // content.
1855   //
1856   // In general, those use cases aren't considered part of the user's normal
1857   // browsing activity.
1858 #if BUILDFLAG(ENABLE_EXTENSIONS)
1859   if (site.SchemeIs(extensions::kExtensionScheme)) {
1860     // The host in an extension site URL is the extension_id.
1861     CHECK(site.has_host());
1862     return extensions::util::GetStoragePartitionConfigForExtensionId(
1863         site.host(), browser_context);
1864   }
1865
1866   if (content::SiteIsolationPolicy::ShouldUrlUseApplicationIsolationLevel(
1867           browser_context, site)) {
1868     CHECK(site.SchemeIs(chrome::kIsolatedAppScheme));
1869     ASSIGN_OR_RETURN(const auto iwa_url_info,
1870                      web_app::IsolatedWebAppUrlInfo::Create(site), [&](auto) {
1871                        LOG(ERROR) << "Invalid isolated-app URL: " << site;
1872                        return default_storage_partition_config;
1873                      });
1874     return iwa_url_info.storage_partition_config(browser_context);
1875   }
1876 #endif
1877
1878   return default_storage_partition_config;
1879 }
1880
1881 std::unique_ptr<content::WebContentsViewDelegate>
1882 ChromeContentBrowserClient::GetWebContentsViewDelegate(
1883     content::WebContents* web_contents) {
1884   Profile* profile =
1885       Profile::FromBrowserContext(web_contents->GetBrowserContext());
1886   // Do not track web contents performance for profiles that have Keyed Services
1887   // disabled.
1888   if (!AreKeyedServicesDisabledForProfileByDefault(profile)) {
1889     if (auto* registry =
1890             performance_manager::PerformanceManagerRegistry::GetInstance()) {
1891       registry->MaybeCreatePageNodeForWebContents(web_contents);
1892     }
1893   }
1894   return CreateWebContentsViewDelegate(web_contents);
1895 }
1896
1897 bool ChromeContentBrowserClient::AllowGpuLaunchRetryOnIOThread() {
1898 #if BUILDFLAG(IS_ANDROID)
1899   const base::android::ApplicationState app_state =
1900       base::android::ApplicationStatusListener::GetState();
1901   return base::android::APPLICATION_STATE_UNKNOWN == app_state ||
1902          base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES == app_state ||
1903          base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES == app_state;
1904 #else
1905   return true;
1906 #endif
1907 }
1908
1909 void ChromeContentBrowserClient::RenderProcessWillLaunch(
1910     content::RenderProcessHost* host) {
1911   Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
1912
1913   WebRtcLoggingController::AttachToRenderProcessHost(
1914       host, g_browser_process->webrtc_log_uploader());
1915
1916   // The audio manager outlives the host, so it's safe to hand a raw pointer to
1917   // it to the AudioDebugRecordingsHandler, which is owned by the host.
1918   AudioDebugRecordingsHandler* audio_debug_recordings_handler =
1919       new AudioDebugRecordingsHandler(profile);
1920   host->SetUserData(
1921       AudioDebugRecordingsHandler::kAudioDebugRecordingsHandlerKey,
1922       std::make_unique<base::UserDataAdapter<AudioDebugRecordingsHandler>>(
1923           audio_debug_recordings_handler));
1924
1925 #if BUILDFLAG(ENABLE_NACL)
1926   if (IsNaclAllowed() && !profile->IsSystemProfile()) {
1927     host->AddFilter(new nacl::NaClHostMessageFilter(
1928         host->GetID(), profile->IsOffTheRecord(), profile->GetPath()));
1929   }
1930 #endif
1931
1932 #if BUILDFLAG(IS_ANDROID)
1933   // Register CrashMemoryMetricsCollector to report oom related metrics.
1934   host->SetUserData(
1935       CrashMemoryMetricsCollector::kCrashMemoryMetricsCollectorKey,
1936       std::make_unique<CrashMemoryMetricsCollector>(host));
1937 #endif
1938
1939   // The RendereUpdater might be null for some irregular profiles, e.g. the
1940   // System Profile.
1941   if (RendererUpdater* service = RendererUpdaterFactory::GetForProfile(profile))
1942     service->InitializeRenderer(host);
1943
1944   for (auto& part : extra_parts_) {
1945     part->RenderProcessWillLaunch(host);
1946   }
1947 }
1948
1949 GURL ChromeContentBrowserClient::GetEffectiveURL(
1950     content::BrowserContext* browser_context,
1951     const GURL& url) {
1952   Profile* profile = Profile::FromBrowserContext(browser_context);
1953   if (!profile)
1954     return url;
1955
1956 #if !BUILDFLAG(IS_ANDROID)
1957   // If the input |url| should be assigned to the Instant renderer, make its
1958   // effective URL distinct from other URLs on the search provider's domain.
1959   // This needs to happen even if |url| corresponds to an isolated origin; see
1960   // https://crbug.com/755595.
1961   if (search::ShouldAssignURLToInstantRenderer(url, profile))
1962     return search::GetEffectiveURLForInstant(url, profile);
1963 #endif
1964
1965 #if BUILDFLAG(ENABLE_EXTENSIONS)
1966   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
1967           profile))
1968     return url;
1969
1970   return ChromeContentBrowserClientExtensionsPart::GetEffectiveURL(profile,
1971                                                                    url);
1972 #else
1973   return url;
1974 #endif
1975 }
1976
1977 bool ChromeContentBrowserClient::
1978     ShouldCompareEffectiveURLsForSiteInstanceSelection(
1979         content::BrowserContext* browser_context,
1980         content::SiteInstance* candidate_site_instance,
1981         bool is_outermost_main_frame,
1982         const GURL& candidate_url,
1983         const GURL& destination_url) {
1984   DCHECK(browser_context);
1985   DCHECK(candidate_site_instance);
1986 #if BUILDFLAG(ENABLE_EXTENSIONS)
1987   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
1988           browser_context)) {
1989     return true;
1990   }
1991
1992   return ChromeContentBrowserClientExtensionsPart::
1993       ShouldCompareEffectiveURLsForSiteInstanceSelection(
1994           browser_context, candidate_site_instance, is_outermost_main_frame,
1995           candidate_url, destination_url);
1996 #else
1997   return true;
1998 #endif
1999 }
2000
2001 bool ChromeContentBrowserClient::ShouldUseMobileFlingCurve() {
2002 #if BUILDFLAG(IS_ANDROID)
2003   return true;
2004 #elif BUILDFLAG(IS_CHROMEOS_ASH)
2005   return ash::TabletMode::IsInTabletMode();
2006 #else
2007   return false;
2008 #endif  // BUILDFLAG(IS_ANDROID)
2009 }
2010
2011 bool ChromeContentBrowserClient::ShouldUseProcessPerSite(
2012     content::BrowserContext* browser_context,
2013     const GURL& site_url) {
2014   Profile* profile = Profile::FromBrowserContext(browser_context);
2015   if (!profile)
2016     return false;
2017
2018   // NTP should use process-per-site.  This is a performance optimization to
2019   // reduce process count associated with NTP tabs.
2020   if (site_url == GURL(chrome::kChromeUINewTabURL) ||
2021       site_url == GURL(chrome::kChromeUINewTabPageURL)) {
2022     return true;
2023   }
2024
2025 #if !BUILDFLAG(IS_ANDROID)
2026   if (search::ShouldUseProcessPerSiteForInstantSiteURL(site_url, profile))
2027     return true;
2028 #endif
2029
2030 #if BUILDFLAG(ENABLE_EXTENSIONS)
2031   if (ChromeContentBrowserClientExtensionsPart::ShouldUseProcessPerSite(
2032           profile, site_url))
2033     return true;
2034 #endif
2035
2036   // Non-extension, non-NTP URLs should generally use process-per-site-instance
2037   // (rather than process-per-site).
2038   return false;
2039 }
2040
2041 bool ChromeContentBrowserClient::ShouldUseSpareRenderProcessHost(
2042     content::BrowserContext* browser_context,
2043     const GURL& site_url) {
2044   Profile* profile = Profile::FromBrowserContext(browser_context);
2045   if (!profile)
2046     return false;
2047
2048   // Returning false here will ensure existing Top chrome WebUI renderers are
2049   // considered for process reuse over the spare renderer.
2050   if (IsTopChromeWebUIURL(site_url) &&
2051       !ShouldUseSpareRenderProcessHostForTopChromePage(profile)) {
2052     return false;
2053   }
2054
2055 #if !BUILDFLAG(IS_ANDROID)
2056   // Instant renderers should not use a spare process, because they require
2057   // passing switches::kInstantProcess to the renderer process when it
2058   // launches.  A spare process is launched earlier, before it is known which
2059   // navigation will use it, so it lacks this flag.
2060   if (search::ShouldAssignURLToInstantRenderer(site_url, profile))
2061     return false;
2062 #endif
2063
2064 #if BUILDFLAG(ENABLE_EXTENSIONS)
2065   return ChromeContentBrowserClientExtensionsPart::
2066       ShouldUseSpareRenderProcessHost(profile, site_url);
2067 #else
2068   return true;
2069 #endif
2070 }
2071
2072 bool ChromeContentBrowserClient::DoesSiteRequireDedicatedProcess(
2073     content::BrowserContext* browser_context,
2074     const GURL& effective_site_url) {
2075   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
2076 #if BUILDFLAG(ENABLE_EXTENSIONS)
2077   if (ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess(
2078           browser_context, effective_site_url)) {
2079     return true;
2080   }
2081 #endif
2082   return false;
2083 }
2084
2085 bool ChromeContentBrowserClient::DoesWebUIUrlRequireProcessLock(
2086     const GURL& url) {
2087   // Note: This method can be called from multiple threads. It is not safe to
2088   // assume it runs only on the UI thread.
2089
2090   // We only allow the most visited tiles on third-party NTPs to not require a
2091   // process lock. Everything else, including the actual third-party NTP which
2092   // embeds those tiles, should be locked.  This allows most visited tiles to
2093   // stay in their parent (i.e., third-party NTP's) process.
2094   if (url.SchemeIs(chrome::kChromeSearchScheme) &&
2095       url.host() == chrome::kChromeSearchMostVisitedHost) {
2096     return false;
2097   }
2098
2099   // All other WebUIs must be locked to origin.
2100   return true;
2101 }
2102
2103 bool ChromeContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
2104     base::StringPiece scheme,
2105     bool is_embedded_origin_secure) {
2106   // This is needed to bypass the normal SameSite rules for any chrome:// page
2107   // embedding a secure origin, regardless of the registrable domains of any
2108   // intervening frames. For example, this is needed for browser UI to interact
2109   // with SameSite cookies on accounts.google.com, which is used for displaying
2110   // a list of available accounts on the NTP (chrome://new-tab-page), etc.
2111   if (is_embedded_origin_secure && scheme == content::kChromeUIScheme)
2112     return true;
2113 #if BUILDFLAG(ENABLE_EXTENSIONS)
2114   return scheme == extensions::kExtensionScheme;
2115 #else
2116   return false;
2117 #endif
2118 }
2119
2120 bool ChromeContentBrowserClient::
2121     ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel(
2122         base::StringPiece scheme,
2123         bool is_embedded_origin_secure) {
2124   return is_embedded_origin_secure && scheme == content::kChromeUIScheme;
2125 }
2126
2127 // TODO(crbug.com/1087559): This is based on SubframeTask::GetTitle()
2128 // implementation. Find a general solution to avoid code duplication.
2129 std::string ChromeContentBrowserClient::GetSiteDisplayNameForCdmProcess(
2130     content::BrowserContext* browser_context,
2131     const GURL& site_url) {
2132   // By default, use the |site_url| spec as the display name.
2133   std::string name = site_url.spec();
2134
2135 #if BUILDFLAG(ENABLE_EXTENSIONS)
2136   // If |site_url| wraps a chrome extension ID, we can display the extension
2137   // name instead, which is more human-readable.
2138   if (site_url.SchemeIs(extensions::kExtensionScheme)) {
2139     const extensions::Extension* extension =
2140         extensions::ExtensionRegistry::Get(browser_context)
2141             ->enabled_extensions()
2142             .GetExtensionOrAppByURL(site_url);
2143     if (extension)
2144       name = extension->name();
2145   }
2146 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
2147
2148   return name;
2149 }
2150
2151 void ChromeContentBrowserClient::OverrideURLLoaderFactoryParams(
2152     content::BrowserContext* browser_context,
2153     const url::Origin& origin,
2154     bool is_for_isolated_world,
2155     network::mojom::URLLoaderFactoryParams* factory_params) {
2156 #if BUILDFLAG(IS_ANDROID)
2157   // Loading state text isn't used on Android, only in desktop UI.
2158   factory_params->provide_loading_state_updates = false;
2159 #endif
2160
2161 #if BUILDFLAG(ENABLE_EXTENSIONS)
2162   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
2163           browser_context)) {
2164     return;
2165   }
2166
2167   ChromeContentBrowserClientExtensionsPart::OverrideURLLoaderFactoryParams(
2168       browser_context, origin, is_for_isolated_world, factory_params);
2169 #endif
2170 }
2171
2172 // These are treated as WebUI schemes but do not get WebUI bindings. Also,
2173 // view-source is allowed for these schemes.
2174 void ChromeContentBrowserClient::GetAdditionalWebUISchemes(
2175     std::vector<std::string>* additional_schemes) {
2176   additional_schemes->emplace_back(chrome::kChromeSearchScheme);
2177   additional_schemes->emplace_back(dom_distiller::kDomDistillerScheme);
2178   additional_schemes->emplace_back(content::kChromeDevToolsScheme);
2179 }
2180
2181 void ChromeContentBrowserClient::GetAdditionalViewSourceSchemes(
2182     std::vector<std::string>* additional_schemes) {
2183   GetAdditionalWebUISchemes(additional_schemes);
2184
2185 #if BUILDFLAG(ENABLE_EXTENSIONS)
2186   additional_schemes->push_back(extensions::kExtensionScheme);
2187 #endif
2188 }
2189
2190 network::mojom::IPAddressSpace
2191 ChromeContentBrowserClient::DetermineAddressSpaceFromURL(const GURL& url) {
2192   if (url.SchemeIs(chrome::kChromeSearchScheme))
2193     return network::mojom::IPAddressSpace::kLocal;
2194   if (url.SchemeIs(dom_distiller::kDomDistillerScheme))
2195     return network::mojom::IPAddressSpace::kPublic;
2196 #if BUILDFLAG(ENABLE_EXTENSIONS)
2197   if (url.SchemeIs(extensions::kExtensionScheme))
2198     return network::mojom::IPAddressSpace::kLocal;
2199 #endif
2200
2201   return network::mojom::IPAddressSpace::kUnknown;
2202 }
2203
2204 bool ChromeContentBrowserClient::LogWebUIUrl(const GURL& web_ui_url) {
2205   return webui::LogWebUIUrl(web_ui_url);
2206 }
2207
2208 bool ChromeContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests(
2209     const url::Origin& origin) {
2210   return ChromeWebUIControllerFactory::IsWebUIAllowedToMakeNetworkRequests(
2211       origin);
2212 }
2213
2214 bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) {
2215   return ProfileIOData::IsHandledURL(url);
2216 }
2217
2218 bool ChromeContentBrowserClient::HasCustomSchemeHandler(
2219     content::BrowserContext* browser_context,
2220     const std::string& scheme) {
2221   if (custom_handlers::ProtocolHandlerRegistry* protocol_handler_registry =
2222           ProtocolHandlerRegistryFactory::GetForBrowserContext(
2223               browser_context)) {
2224     return protocol_handler_registry->IsHandledProtocol(scheme);
2225   }
2226
2227   return false;
2228 }
2229
2230 bool ChromeContentBrowserClient::CanCommitURL(
2231     content::RenderProcessHost* process_host,
2232     const GURL& url) {
2233 #if BUILDFLAG(ENABLE_EXTENSIONS)
2234   return ChromeContentBrowserClientExtensionsPart::CanCommitURL(process_host,
2235                                                                 url);
2236 #else
2237   return true;
2238 #endif
2239 }
2240
2241 void ChromeContentBrowserClient::OverrideNavigationParams(
2242     absl::optional<GURL> source_process_site_url,
2243     ui::PageTransition* transition,
2244     bool* is_renderer_initiated,
2245     content::Referrer* referrer,
2246     absl::optional<url::Origin>* initiator_origin) {
2247   DCHECK(transition);
2248   DCHECK(is_renderer_initiated);
2249   DCHECK(referrer);
2250   // IsNTPURL only looks at the origin of the parameter, so it is safe to use
2251   // the effective site URL for the source process.
2252   if (source_process_site_url &&
2253       search::IsNTPURL(source_process_site_url.value()) &&
2254       ui::PageTransitionCoreTypeIs(*transition, ui::PAGE_TRANSITION_LINK)) {
2255     // Clicks on tiles of the new tab page should be treated as if a user
2256     // clicked on a bookmark.  This is consistent with native implementations
2257     // like Android's.  This also helps ensure that security features (like
2258     // Sec-Fetch-Site and SameSite-cookies) will treat the navigation as
2259     // browser-initiated.
2260     *transition = ui::PAGE_TRANSITION_AUTO_BOOKMARK;
2261     *is_renderer_initiated = false;
2262     *referrer = content::Referrer();
2263     *initiator_origin = absl::nullopt;
2264   }
2265 }
2266
2267 bool ChromeContentBrowserClient::ShouldStayInParentProcessForNTP(
2268     const GURL& url,
2269     const GURL& parent_site_url) {
2270   // Allow most visited iframes to stay in the parent process but only if that
2271   // process is for NTP.
2272   //
2273   // TODO(alexmos): Consider further tightening this exception to just the
2274   // third-party remote NTP in the parent, rather than any NTP.
2275   //
2276   // TODO(crbug.com/566091): place those iframes into OOPIFs and remove this
2277   // exception. Relaxing site isolation like this is a bad idea and should be
2278   // avoided.
2279   //
2280   // TODO(crbug.com/624410): clean up the logic for detecting NTP.
2281   return url.SchemeIs(chrome::kChromeSearchScheme) &&
2282          url.host() == chrome::kChromeSearchMostVisitedHost &&
2283          search::IsNTPURL(parent_site_url);
2284 }
2285
2286 bool ChromeContentBrowserClient::IsSuitableHost(
2287     content::RenderProcessHost* process_host,
2288     const GURL& site_url) {
2289   Profile* profile =
2290       Profile::FromBrowserContext(process_host->GetBrowserContext());
2291   // This may be nullptr during tests. In that case, just assume any site can
2292   // share any host.
2293   if (!profile)
2294     return true;
2295
2296 #if !BUILDFLAG(IS_ANDROID)
2297   // Instant URLs should only be in the instant process and instant process
2298   // should only have Instant URLs.
2299   InstantService* instant_service =
2300       InstantServiceFactory::GetForProfile(profile);
2301   if (instant_service) {
2302     bool is_instant_process =
2303         instant_service->IsInstantProcess(process_host->GetID());
2304     bool should_be_in_instant_process =
2305         search::ShouldAssignURLToInstantRenderer(site_url, profile);
2306     if (is_instant_process || should_be_in_instant_process)
2307       return is_instant_process && should_be_in_instant_process;
2308   }
2309 #endif
2310
2311 #if BUILDFLAG(ENABLE_EXTENSIONS)
2312   return ChromeContentBrowserClientExtensionsPart::IsSuitableHost(
2313       profile, process_host, site_url);
2314 #else
2315   return true;
2316 #endif
2317 }
2318
2319 bool ChromeContentBrowserClient::MayReuseHost(
2320     content::RenderProcessHost* process_host) {
2321   // If there is currently a no-state prefetcher in progress for the host
2322   // provided, it may not be shared. We require prefetchers to be by themselves
2323   // in a separate process so that we can monitor their resource usage.
2324   prerender::NoStatePrefetchManager* no_state_prefetch_manager =
2325       prerender::NoStatePrefetchManagerFactory::GetForBrowserContext(
2326           process_host->GetBrowserContext());
2327   if (no_state_prefetch_manager &&
2328       !no_state_prefetch_manager->MayReuseProcessHost(process_host)) {
2329     return false;
2330   }
2331
2332   return true;
2333 }
2334
2335 size_t ChromeContentBrowserClient::GetProcessCountToIgnoreForLimit() {
2336 #if BUILDFLAG(ENABLE_EXTENSIONS)
2337   return ChromeContentBrowserClientExtensionsPart::
2338       GetProcessCountToIgnoreForLimit();
2339 #else
2340   return 0;
2341 #endif
2342 }
2343
2344 absl::optional<blink::ParsedPermissionsPolicy>
2345 ChromeContentBrowserClient::GetPermissionsPolicyForIsolatedWebApp(
2346     content::BrowserContext* browser_context,
2347     const url::Origin& app_origin) {
2348 #if !BUILDFLAG(IS_ANDROID)
2349   // Extensions are exempt from manifest policy enforcement and retain the
2350   // default frame permissions policy.
2351   if (app_origin.scheme() == extensions::kExtensionScheme) {
2352     return absl::nullopt;
2353   }
2354
2355   Profile* profile = Profile::FromBrowserContext(browser_context);
2356   auto& registrar =
2357       web_app::WebAppProvider::GetForWebApps(profile)->registrar_unsafe();
2358   std::vector<webapps::AppId> app_ids_for_origin =
2359       registrar.FindAppsInScope(app_origin.GetURL());
2360   if (app_ids_for_origin.empty()) {
2361     return blink::ParsedPermissionsPolicy();
2362   }
2363
2364   return registrar.GetPermissionsPolicy(app_ids_for_origin[0]);
2365 #else
2366   NOTIMPLEMENTED();
2367   return blink::ParsedPermissionsPolicy();
2368 #endif
2369 }
2370
2371 bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost(
2372     content::BrowserContext* browser_context,
2373     const GURL& url) {
2374   // Top Chrome WebUI should try to share a RenderProcessHost with other
2375   // existing Top Chrome WebUI.
2376   if (IsTopChromeWebUIURL(url))
2377     return true;
2378
2379   return false;
2380 }
2381
2382 bool ChromeContentBrowserClient::ShouldEmbeddedFramesTryToReuseExistingProcess(
2383     content::RenderFrameHost* outermost_main_frame) {
2384 #if BUILDFLAG(ENABLE_EXTENSIONS)
2385   return ChromeContentBrowserClientExtensionsPart::
2386       ShouldEmbeddedFramesTryToReuseExistingProcess(outermost_main_frame);
2387 #else
2388   return true;
2389 #endif
2390 }
2391
2392 void ChromeContentBrowserClient::SiteInstanceGotProcess(
2393     SiteInstance* site_instance) {
2394   CHECK(site_instance->HasProcess());
2395
2396   Profile* profile =
2397       Profile::FromBrowserContext(site_instance->GetBrowserContext());
2398   if (!profile)
2399     return;
2400
2401 #if !BUILDFLAG(IS_ANDROID)
2402   // Remember the ID of the Instant process to signal the renderer process
2403   // on startup in |AppendExtraCommandLineSwitches| below.
2404   if (search::ShouldAssignURLToInstantRenderer(site_instance->GetSiteURL(),
2405                                                profile)) {
2406     InstantService* instant_service =
2407         InstantServiceFactory::GetForProfile(profile);
2408     if (instant_service)
2409       instant_service->AddInstantProcess(site_instance->GetProcess());
2410   }
2411 #endif
2412
2413   for (auto& part : extra_parts_) {
2414     part->SiteInstanceGotProcess(site_instance);
2415   }
2416 }
2417
2418 bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
2419     SiteInstance* site_instance,
2420     const GURL& current_effective_url,
2421     const GURL& destination_effective_url) {
2422 #if BUILDFLAG(ENABLE_EXTENSIONS)
2423   return ChromeContentBrowserClientExtensionsPart::
2424       ShouldSwapBrowsingInstancesForNavigation(
2425           site_instance, current_effective_url, destination_effective_url);
2426 #else
2427   return false;
2428 #endif
2429 }
2430
2431 bool ChromeContentBrowserClient::ShouldIsolateErrorPage(bool in_main_frame) {
2432   // TODO(nasko): Consider supporting error page isolation in subframes if
2433   // Site Isolation is enabled.
2434   return in_main_frame;
2435 }
2436
2437 std::vector<url::Origin>
2438 ChromeContentBrowserClient::GetOriginsRequiringDedicatedProcess() {
2439   std::vector<url::Origin> isolated_origin_list;
2440
2441   if (DoesGaiaOriginRequireDedicatedProcess()) {
2442     isolated_origin_list.push_back(GaiaUrls::GetInstance()->gaia_origin());
2443   }
2444
2445 #if BUILDFLAG(ENABLE_EXTENSIONS)
2446   auto origins_from_extensions = ChromeContentBrowserClientExtensionsPart::
2447       GetOriginsRequiringDedicatedProcess();
2448   std::move(std::begin(origins_from_extensions),
2449             std::end(origins_from_extensions),
2450             std::back_inserter(isolated_origin_list));
2451 #endif
2452
2453   // Include additional origins preloaded with specific browser configurations,
2454   // if any.  For example, this is used on Google Chrome for Android to preload
2455   // a list of important sites to isolate.
2456   auto built_in_origins =
2457       site_isolation::GetBrowserSpecificBuiltInIsolatedOrigins();
2458   std::move(std::begin(built_in_origins), std::end(built_in_origins),
2459             std::back_inserter(isolated_origin_list));
2460
2461   return isolated_origin_list;
2462 }
2463
2464 bool ChromeContentBrowserClient::ShouldEnableStrictSiteIsolation() {
2465   return base::FeatureList::IsEnabled(features::kSitePerProcess);
2466 }
2467
2468 bool ChromeContentBrowserClient::ShouldDisableSiteIsolation(
2469     content::SiteIsolationMode site_isolation_mode) {
2470   return site_isolation::SiteIsolationPolicy::
2471       ShouldDisableSiteIsolationDueToMemoryThreshold(site_isolation_mode);
2472 }
2473
2474 std::vector<std::string>
2475 ChromeContentBrowserClient::GetAdditionalSiteIsolationModes() {
2476   std::vector<std::string> modes;
2477   if (site_isolation::SiteIsolationPolicy::IsIsolationForPasswordSitesEnabled())
2478     modes.push_back("Password Sites");
2479   if (site_isolation::SiteIsolationPolicy::IsIsolationForOAuthSitesEnabled())
2480     modes.push_back("Logged-in Sites");
2481   return modes;
2482 }
2483
2484 void ChromeContentBrowserClient::PersistIsolatedOrigin(
2485     content::BrowserContext* context,
2486     const url::Origin& origin,
2487     content::ChildProcessSecurityPolicy::IsolatedOriginSource source) {
2488   site_isolation::SiteIsolationPolicy::PersistIsolatedOrigin(context, origin,
2489                                                              source);
2490 }
2491
2492 bool ChromeContentBrowserClient::ShouldUrlUseApplicationIsolationLevel(
2493     content::BrowserContext* browser_context,
2494     const GURL& url) {
2495 #if BUILDFLAG(ENABLE_EXTENSIONS)
2496
2497   if (!content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
2498           browser_context)) {
2499     return false;
2500   }
2501
2502   // Convert |url| to an origin to resolve blob: URLs.
2503   auto origin = url::Origin::Create(url);
2504   if (origin.scheme() == chrome::kIsolatedAppScheme) {
2505     return true;
2506   }
2507 #endif
2508   return false;
2509 }
2510
2511 bool ChromeContentBrowserClient::IsIsolatedContextAllowedForUrl(
2512     content::BrowserContext* browser_context,
2513     const GURL& lock_url) {
2514 #if BUILDFLAG(IS_CHROMEOS)
2515   if (base::FeatureList::IsEnabled(features::kWebKioskEnableIwaApis) &&
2516       chromeos::IsWebKioskSession()) {
2517     return true;
2518   }
2519 #endif
2520 #if BUILDFLAG(IS_CHROMEOS_ASH)
2521   if (lock_url == chrome::kChromeUIUntrustedTerminalURL) {
2522     return true;
2523   }
2524 #endif
2525
2526 #if BUILDFLAG(ENABLE_EXTENSIONS)
2527   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
2528           browser_context)) {
2529     return false;
2530   }
2531
2532   // Allow restricted context APIs in Chrome Apps.
2533   auto* extension = extensions::ExtensionRegistry::Get(browser_context)
2534                         ->enabled_extensions()
2535                         .GetExtensionOrAppByURL(lock_url);
2536   return extension &&
2537          (extension->is_platform_app() ||
2538           IsExtensionIdAllowedToUseIsolatedContext(extension->id()));
2539 #else
2540   return false;
2541 #endif
2542 }
2543
2544 bool ChromeContentBrowserClient::IsGetAllScreensMediaAllowed(
2545     content::BrowserContext* context,
2546     const url::Origin& origin) {
2547   return capture_policy::IsGetAllScreensMediaAllowed(context, origin.GetURL());
2548 }
2549
2550 bool ChromeContentBrowserClient::IsFileAccessAllowed(
2551     const base::FilePath& path,
2552     const base::FilePath& absolute_path,
2553     const base::FilePath& profile_path) {
2554   return ChromeNetworkDelegate::IsAccessAllowed(path, absolute_path,
2555                                                 profile_path);
2556 }
2557
2558 namespace {
2559
2560 void MaybeAppendBlinkSettingsSwitchForFieldTrial(
2561     const base::CommandLine& browser_command_line,
2562     base::CommandLine* command_line) {
2563   // List of field trials that modify the blink-settings command line flag. No
2564   // two field trials in the list should specify the same keys, otherwise one
2565   // field trial may overwrite another. See Source/core/frame/Settings.in in
2566   // Blink for the list of valid keys.
2567   static const char* const kBlinkSettingsFieldTrials[] = {
2568       // Keys: disallowFetchForDocWrittenScriptsInMainFrame
2569       //       disallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections
2570       //       disallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G
2571       "DisallowFetchForDocWrittenScriptsInMainFrame",
2572   };
2573
2574   std::vector<std::string> blink_settings;
2575   for (const char* field_trial_name : kBlinkSettingsFieldTrials) {
2576     // Each blink-settings field trial should include a forcing_flag group,
2577     // to make sure that clients that specify the blink-settings flag on the
2578     // command line are excluded from the experiment groups. To make
2579     // sure we assign clients that specify this flag to the forcing_flag
2580     // group, we must call GetFieldTrialParams for each field trial first
2581     // (for example, before checking HasSwitch() and returning), since
2582     // GetFieldTrialParams has the side-effect of assigning the client to
2583     // a field trial group.
2584     std::map<std::string, std::string> params;
2585     if (base::GetFieldTrialParams(field_trial_name, &params)) {
2586       for (const auto& param : params) {
2587         blink_settings.push_back(base::StringPrintf(
2588             "%s=%s", param.first.c_str(), param.second.c_str()));
2589       }
2590     }
2591   }
2592
2593   if (blink_settings.empty()) {
2594     return;
2595   }
2596
2597   if (browser_command_line.HasSwitch(blink::switches::kBlinkSettings) ||
2598       command_line->HasSwitch(blink::switches::kBlinkSettings)) {
2599     // The field trials should be configured to force users that specify the
2600     // blink-settings flag into a group with no params, and we return
2601     // above if no params were specified, so it's an error if we reach
2602     // this point.
2603     LOG(WARNING) << "Received field trial params, "
2604                     "but blink-settings switch already specified.";
2605     return;
2606   }
2607
2608   command_line->AppendSwitchASCII(blink::switches::kBlinkSettings,
2609                                   base::JoinString(blink_settings, ","));
2610 }
2611
2612 }  // namespace
2613
2614 void ChromeContentBrowserClient::AppendExtraCommandLineSwitches(
2615     base::CommandLine* command_line,
2616     int child_process_id) {
2617 #if BUILDFLAG(IS_MAC)
2618   std::unique_ptr<metrics::ClientInfo> client_info =
2619       GoogleUpdateSettings::LoadMetricsClientInfo();
2620   if (client_info) {
2621     command_line->AppendSwitchASCII(switches::kMetricsClientID,
2622                                     client_info->client_id);
2623   }
2624 #elif BUILDFLAG(IS_POSIX)
2625 #if BUILDFLAG(IS_ANDROID)
2626   bool enable_crash_reporter = true;
2627 #elif BUILDFLAG(IS_CHROMEOS)
2628   bool enable_crash_reporter = false;
2629   if (crash_reporter::IsCrashpadEnabled()) {
2630     command_line->AppendSwitch(switches::kEnableCrashpad);
2631     enable_crash_reporter = true;
2632
2633     int fd;
2634     pid_t pid;
2635     if (crash_reporter::GetHandlerSocket(&fd, &pid)) {
2636       command_line->AppendSwitchASCII(
2637           crash_reporter::switches::kCrashpadHandlerPid,
2638           base::NumberToString(pid));
2639     }
2640   } else {
2641     enable_crash_reporter = breakpad::IsCrashReporterEnabled();
2642   }
2643 #else
2644   bool enable_crash_reporter = true;
2645   pid_t pid;
2646   if (crash_reporter::GetHandlerSocket(nullptr, &pid)) {
2647     command_line->AppendSwitchASCII(
2648         crash_reporter::switches::kCrashpadHandlerPid,
2649         base::NumberToString(pid));
2650   }
2651 #endif
2652   if (enable_crash_reporter) {
2653     std::string switch_value;
2654     std::unique_ptr<metrics::ClientInfo> client_info =
2655         GoogleUpdateSettings::LoadMetricsClientInfo();
2656     if (client_info)
2657       switch_value = client_info->client_id;
2658     switch_value.push_back(',');
2659     switch_value.append(
2660         chrome::GetChannelName(chrome::WithExtendedStable(true)));
2661     command_line->AppendSwitchASCII(switches::kEnableCrashReporter,
2662                                     switch_value);
2663   }
2664 #endif
2665
2666   if (logging::DialogsAreSuppressed())
2667     command_line->AppendSwitch(switches::kNoErrorDialogs);
2668
2669   std::string process_type =
2670       command_line->GetSwitchValueASCII(switches::kProcessType);
2671   const base::CommandLine& browser_command_line =
2672       *base::CommandLine::ForCurrentProcess();
2673
2674 #if BUILDFLAG(IS_CHROMEOS_LACROS)
2675   // Pass startup and post-login parameter FDs to child processes in Lacros.
2676   if (process_type != switches::kZygoteProcess) {
2677     constexpr int kStartupDataFD =
2678         kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor;
2679     command_line->AppendSwitchASCII(chromeos::switches::kCrosStartupDataFD,
2680                                     base::NumberToString(kStartupDataFD));
2681
2682     if (chromeos::IsLaunchedWithPostLoginParams()) {
2683       constexpr int kPostLoginDataFD = kCrosPostLoginDataDescriptor +
2684                                        base::GlobalDescriptors::kBaseDescriptor;
2685       command_line->AppendSwitchASCII(chromeos::switches::kCrosPostLoginDataFD,
2686                                       base::NumberToString(kPostLoginDataFD));
2687     }
2688   }
2689 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
2690
2691   static const char* const kCommonSwitchNames[] = {
2692       embedder_support::kUserAgent,
2693       switches::kUserDataDir,  // Make logs go to the right file.
2694   };
2695   command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames);
2696
2697   static const char* const kDinosaurEasterEggSwitches[] = {
2698       error_page::switches::kDisableDinosaurEasterEgg,
2699   };
2700   command_line->CopySwitchesFrom(browser_command_line,
2701                                  kDinosaurEasterEggSwitches);
2702
2703 #if BUILDFLAG(IS_CHROMEOS_ASH)
2704   // On Chrome OS need to pass primary user homedir (in multi-profiles session).
2705   base::FilePath homedir;
2706   base::PathService::Get(base::DIR_HOME, &homedir);
2707   command_line->AppendSwitchASCII(ash::switches::kHomedir, homedir.value());
2708 #endif
2709
2710   if (process_type == switches::kRendererProcess) {
2711     content::RenderProcessHost* process =
2712         content::RenderProcessHost::FromID(child_process_id);
2713     Profile* profile =
2714         process ? Profile::FromBrowserContext(process->GetBrowserContext())
2715                 : nullptr;
2716     for (auto& part : extra_parts_) {
2717       part->AppendExtraRendererCommandLineSwitches(command_line, process,
2718                                                    profile);
2719     }
2720
2721 #if BUILDFLAG(IS_CHROMEOS_ASH)
2722     const std::string& login_profile =
2723         browser_command_line.GetSwitchValueASCII(ash::switches::kLoginProfile);
2724     if (!login_profile.empty()) {
2725       command_line->AppendSwitchASCII(ash::switches::kLoginProfile,
2726                                       login_profile);
2727     }
2728 #endif
2729
2730     MaybeCopyDisableWebRtcEncryptionSwitch(command_line, browser_command_line,
2731                                            chrome::GetChannel());
2732     if (process) {
2733       PrefService* prefs = profile->GetPrefs();
2734       // Currently this pref is only registered if applied via a policy.
2735       if (prefs->HasPrefPath(prefs::kDisable3DAPIs) &&
2736           prefs->GetBoolean(prefs::kDisable3DAPIs)) {
2737         // Turn this policy into a command line switch.
2738         command_line->AppendSwitch(switches::kDisable3DAPIs);
2739       }
2740
2741       if (prefs->GetBoolean(prefs::kPrintPreviewDisabled))
2742         command_line->AppendSwitch(switches::kDisablePrintPreview);
2743
2744       // This passes the preference set by an enterprise policy on to a blink
2745       // switch so that we know whether to force WebSQL to be enabled.
2746       if (prefs->GetBoolean(storage::kWebSQLAccess)) {
2747         command_line->AppendSwitch(blink::switches::kWebSQLAccess);
2748       }
2749
2750       if (prefs->GetBoolean(prefs::kDataUrlInSvgUseEnabled)) {
2751         command_line->AppendSwitch(blink::switches::kDataUrlInSvgUseEnabled);
2752       }
2753
2754       if (prefs->GetBoolean(policy::policy_prefs::
2755                                 kForcePermissionPolicyUnloadDefaultEnabled)) {
2756         command_line->AppendSwitch(
2757             blink::switches::kForcePermissionPolicyUnloadDefaultEnabled);
2758       }
2759
2760 #if !BUILDFLAG(IS_ANDROID)
2761       InstantService* instant_service =
2762           InstantServiceFactory::GetForProfile(profile);
2763       if (instant_service &&
2764           instant_service->IsInstantProcess(process->GetID())) {
2765         command_line->AppendSwitch(switches::kInstantProcess);
2766       }
2767
2768       // Enable SharedArrayBuffer on desktop if allowed by Enterprise Policy.
2769       // TODO(crbug.com/1144104) Remove when migration to COOP+COEP is complete.
2770       if (prefs->GetBoolean(
2771               prefs::kSharedArrayBufferUnrestrictedAccessAllowed)) {
2772         command_line->AppendSwitch(
2773             switches::kSharedArrayBufferUnrestrictedAccessAllowed);
2774       }
2775 #endif
2776       if (!prefs->GetBoolean(prefs::kSandboxExternalProtocolBlocked))
2777         command_line->AppendSwitch(kDisableSandboxExternalProtocolSwitch);
2778
2779       if (prefs->HasPrefPath(prefs::kAllowDinosaurEasterEgg) &&
2780           !prefs->GetBoolean(prefs::kAllowDinosaurEasterEgg)) {
2781         command_line->AppendSwitch(
2782             error_page::switches::kDisableDinosaurEasterEgg);
2783       }
2784
2785       MaybeAppendSecureOriginsAllowlistSwitch(command_line);
2786
2787       if (prefs->HasPrefPath(prefs::kScrollToTextFragmentEnabled) &&
2788           !prefs->GetBoolean(prefs::kScrollToTextFragmentEnabled)) {
2789         command_line->AppendSwitch(switches::kDisableScrollToTextFragment);
2790       }
2791
2792       // Override OffsetParentNewSpecBehavior feature if its Enterprise policy
2793       // is specified.
2794       if (prefs->HasPrefPath(
2795               policy::policy_prefs::kOffsetParentNewSpecBehaviorEnabled)) {
2796         command_line->AppendSwitchASCII(
2797             blink::switches::kOffsetParentNewSpecBehaviorPolicy,
2798             prefs->GetBoolean(
2799                 policy::policy_prefs::kOffsetParentNewSpecBehaviorEnabled)
2800                 ? blink::switches::
2801                       kOffsetParentNewSpecBehaviorPolicy_ForceEnable
2802                 : blink::switches::
2803                       kOffsetParentNewSpecBehaviorPolicy_ForceDisable);
2804       }
2805       // Override SendMouseEventsDisabledFormControls feature if its Enterprise
2806       // Policy is specified.
2807       if (prefs->HasPrefPath(policy::policy_prefs::
2808                                  kSendMouseEventsDisabledFormControlsEnabled)) {
2809         command_line->AppendSwitchASCII(
2810             blink::switches::kSendMouseEventsDisabledFormControlsPolicy,
2811             prefs->GetBoolean(policy::policy_prefs::
2812                                   kSendMouseEventsDisabledFormControlsEnabled)
2813                 ? blink::switches::
2814                       kSendMouseEventsDisabledFormControlsPolicy_ForceEnable
2815                 : blink::switches::
2816                       kSendMouseEventsDisabledFormControlsPolicy_ForceDisable);
2817       }
2818
2819       if (!prefs->GetList(enterprise_reporting::kCloudLegacyTechReportAllowlist)
2820                .empty()) {
2821         command_line->AppendSwitch(
2822             blink::switches::kLegacyTechReportPolicyEnabled);
2823       }
2824
2825       // The IntensiveWakeUpThrottling feature is typically managed via a
2826       // base::Feature, but it has a managed policy override. The override is
2827       // communicated to blink via a custom command-line flag. See
2828       // PageSchedulerImpl for the other half of related logic.
2829       PrefService* local_state = g_browser_process->local_state();
2830       const PrefService::Preference* pref = local_state->FindPreference(
2831           policy::policy_prefs::kIntensiveWakeUpThrottlingEnabled);
2832       if (pref && pref->IsManaged()) {
2833         command_line->AppendSwitchASCII(
2834             blink::switches::kIntensiveWakeUpThrottlingPolicy,
2835             pref->GetValue()->GetBool()
2836                 ? blink::switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable
2837                 : blink::switches::
2838                       kIntensiveWakeUpThrottlingPolicy_ForceDisable);
2839       }
2840
2841 #if BUILDFLAG(IS_ANDROID)
2842       // Communicating to content/ for BackForwardCache.
2843       if (prefs->HasPrefPath(policy::policy_prefs::kBackForwardCacheEnabled) &&
2844           !prefs->GetBoolean(policy::policy_prefs::kBackForwardCacheEnabled)) {
2845         command_line->AppendSwitch(switches::kDisableBackForwardCache);
2846       }
2847 #endif  // BUILDFLAG(IS_ANDROID)
2848
2849 #if !BUILDFLAG(IS_ANDROID)
2850       // Make the WebAuthenticationRemoteProxiedRequestsAllowed policy enable
2851       // the experimental WebAuthenticationRemoteDesktopSupport Blink runtime
2852       // feature.
2853       if (prefs->GetBoolean(
2854               webauthn::pref_names::kRemoteProxiedRequestsAllowed)) {
2855         command_line->AppendSwitch(switches::kWebAuthRemoteDesktopSupport);
2856       }
2857
2858       if (IsCartModuleEnabled()) {
2859         command_line->AppendSwitch(commerce::switches::kEnableChromeCart);
2860       }
2861 #endif
2862
2863       if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
2864               process->GetBrowserContext())) {
2865         command_line->AppendSwitch(switches::kEnableIsolatedWebAppsInRenderer);
2866       }
2867     }
2868
2869     MaybeAppendBlinkSettingsSwitchForFieldTrial(browser_command_line,
2870                                                 command_line);
2871
2872 #if BUILDFLAG(IS_ANDROID)
2873     // If the platform is Android, force the distillability service on.
2874     command_line->AppendSwitch(switches::kEnableDistillabilityService);
2875 #endif
2876
2877 #if BUILDFLAG(ENABLE_NACL)
2878     AppendDisableNaclSwitchIfNecessary(command_line);
2879 #endif
2880
2881     // Please keep this in alphabetical order.
2882     static const char* const kSwitchNames[] = {
2883       autofill::switches::kIgnoreAutocompleteOffForAutofill,
2884       autofill::switches::kShowAutofillSignatures,
2885 #if BUILDFLAG(IS_CHROMEOS_ASH)
2886       switches::kShortMergeSessionTimeoutForTest,  // For tests only.
2887 #endif
2888 #if BUILDFLAG(ENABLE_EXTENSIONS)
2889       extensions::switches::kAllowHTTPBackgroundPage,
2890       extensions::switches::kAllowLegacyExtensionManifests,
2891       extensions::switches::kDisableExtensionsHttpThrottling,
2892       extensions::switches::kEnableExperimentalExtensionApis,
2893       extensions::switches::kExtensionsOnChromeURLs,
2894       extensions::switches::kSetExtensionThrottleTestParams,  // For tests only.
2895       extensions::switches::kAllowlistedExtensionID,
2896 #endif
2897       switches::kAllowInsecureLocalhost,
2898       switches::kAppsGalleryURL,
2899       switches::kDisableJavaScriptHarmonyShipping,
2900       variations::switches::kEnableBenchmarking,
2901       switches::kEnableDistillabilityService,
2902       switches::kEnableNaCl,
2903 #if BUILDFLAG(ENABLE_NACL)
2904       switches::kEnableNaClDebug,
2905 #endif
2906       switches::kEnableNetBenchmarking,
2907 #if BUILDFLAG(IS_CHROMEOS)
2908       chromeos::switches::
2909           kTelemetryExtensionPwaOriginOverrideForTesting,  // For tests only.
2910       switches::kForceAppMode,
2911 #endif
2912 #if BUILDFLAG(ENABLE_NACL)
2913       switches::kForcePNaClSubzero,
2914 #endif
2915       switches::kForceUIDirection,
2916       switches::kIgnoreGooglePortNumbers,
2917       switches::kJavaScriptHarmony,
2918       switches::kEnableExperimentalWebAssemblyFeatures,
2919       embedder_support::kOriginTrialDisabledFeatures,
2920       embedder_support::kOriginTrialPublicKey,
2921       switches::kReaderModeHeuristics,
2922       translate::switches::kTranslateSecurityOrigin,
2923     };
2924
2925     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames);
2926   } else if (process_type == switches::kUtilityProcess) {
2927 #if BUILDFLAG(ENABLE_EXTENSIONS)
2928     static const char* const kSwitchNames[] = {
2929         extensions::switches::kAllowHTTPBackgroundPage,
2930         extensions::switches::kEnableExperimentalExtensionApis,
2931         extensions::switches::kExtensionsOnChromeURLs,
2932         extensions::switches::kAllowlistedExtensionID,
2933     };
2934
2935     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames);
2936 #endif
2937     MaybeAppendSecureOriginsAllowlistSwitch(command_line);
2938   } else if (process_type == switches::kZygoteProcess) {
2939     // It would be preferable to call AppendDisableNaclSwitchIfNecessary to
2940     // disable NaCl for the zygote process. Unfortunately that method depends on
2941     // state (including policy) that is determined after the zygote is forked.
2942     // Instead we rely on renderers overriding the zygote state.
2943
2944     // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox.
2945 #if BUILDFLAG(ENABLE_NACL)
2946     static const char* const kSwitchNames[] = {
2947         switches::kEnableNaClDebug,
2948         switches::kForcePNaClSubzero,
2949         switches::kVerboseLoggingInNacl,
2950     };
2951
2952     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames);
2953 #endif
2954 #if BUILDFLAG(IS_CHROMEOS_LACROS)
2955     // Ensure zygote loads the resource bundle for the right locale.
2956     static const char* const kMoreSwitchNames[] = {switches::kLang};
2957     command_line->CopySwitchesFrom(browser_command_line, kMoreSwitchNames);
2958 #endif
2959 #if BUILDFLAG(IS_CHROMEOS)
2960     // This is called before feature flags are parsed, so pass them in their raw
2961     // form.
2962     static const char* const kMoreCrOSSwitchNames[] = {
2963         chromeos::switches::kFeatureFlags};
2964     command_line->CopySwitchesFrom(browser_command_line, kMoreCrOSSwitchNames);
2965 #endif
2966   } else if (process_type == switches::kGpuProcess) {
2967     // If --ignore-gpu-blocklist is passed in, don't send in crash reports
2968     // because GPU is expected to be unreliable.
2969     if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlocklist) &&
2970         !command_line->HasSwitch(switches::kDisableBreakpad))
2971       command_line->AppendSwitch(switches::kDisableBreakpad);
2972   }
2973
2974 #if BUILDFLAG(IS_CHROMEOS_ASH)
2975   if (ChromeCrashReporterClient::ShouldPassCrashLoopBefore(process_type)) {
2976     static const char* const kSwitchNames[] = {
2977         crash_reporter::switches::kCrashLoopBefore,
2978     };
2979     command_line->CopySwitchesFrom(browser_command_line, kSwitchNames);
2980   }
2981 #endif
2982
2983 #if BUILDFLAG(IS_WIN)
2984   if (base::FeatureList::IsEnabled(features::kNoPreReadMainDll)) {
2985     command_line->AppendSwitch(switches::kNoPreReadMainDll);
2986   }
2987 #endif
2988
2989   ThreadProfilerConfiguration::Get()->AppendCommandLineSwitchForChildProcess(
2990       command_line);
2991
2992 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH)
2993   // Opt into a hardened stack canary mitigation if it hasn't already been
2994   // force-disabled.
2995 #if !BUILDFLAG(IS_TIZEN)
2996   // Causes "stack smashing detected" error on utility service during launch.
2997   if (!browser_command_line.HasSwitch(switches::kChangeStackGuardOnFork)) {
2998     command_line->AppendSwitchASCII(switches::kChangeStackGuardOnFork,
2999                                     switches::kChangeStackGuardOnForkEnabled);
3000   }
3001 #endif
3002 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
3003   if (process_type != switches::kZygoteProcess) {
3004     DCHECK(g_browser_process);
3005     PrefService* local_state = g_browser_process->local_state();
3006     DCHECK(local_state);
3007     if (!local_state->GetBoolean(
3008             policy::policy_prefs::kPPAPISharedImagesForVideoDecoderAllowed)) {
3009       command_line->AppendSwitch(
3010           ::switches::kDisableUseSharedImagesForPepperVideo);
3011     }
3012   }
3013 }
3014
3015 std::string
3016 ChromeContentBrowserClient::GetApplicationClientGUIDForQuarantineCheck() {
3017   return std::string(chrome::kApplicationClientIDStringForAVScanning);
3018 }
3019
3020 download::QuarantineConnectionCallback
3021 ChromeContentBrowserClient::GetQuarantineConnectionCallback() {
3022   return base::BindRepeating(
3023       &ChromeDownloadManagerDelegate::ConnectToQuarantineService);
3024 }
3025
3026 std::string ChromeContentBrowserClient::GetApplicationLocale() {
3027   if (BrowserThread::CurrentlyOn(BrowserThread::IO))
3028     return GetIOThreadApplicationLocale();
3029   return g_browser_process->GetApplicationLocale();
3030 }
3031
3032 std::string ChromeContentBrowserClient::GetAcceptLangs(
3033     content::BrowserContext* context) {
3034   Profile* profile = Profile::FromBrowserContext(context);
3035   return profile->GetPrefs()->GetString(language::prefs::kAcceptLanguages);
3036 }
3037
3038 gfx::ImageSkia ChromeContentBrowserClient::GetDefaultFavicon() {
3039   return favicon::GetDefaultFavicon().AsImageSkia();
3040 }
3041
3042 bool ChromeContentBrowserClient::IsDataSaverEnabled(
3043     content::BrowserContext* browser_context) {
3044   if (!browser_context || browser_context->IsOffTheRecord())
3045     return false;
3046
3047   return data_saver::IsDataSaverEnabled();
3048 }
3049
3050 void ChromeContentBrowserClient::UpdateRendererPreferencesForWorker(
3051     content::BrowserContext* browser_context,
3052     blink::RendererPreferences* out_prefs) {
3053   DCHECK(browser_context);
3054   DCHECK(out_prefs);
3055   renderer_preferences_util::UpdateFromSystemSettings(
3056       out_prefs, Profile::FromBrowserContext(browser_context));
3057 }
3058
3059 content::AllowServiceWorkerResult
3060 ChromeContentBrowserClient::AllowServiceWorker(
3061     const GURL& scope,
3062     const net::SiteForCookies& site_for_cookies,
3063     const absl::optional<url::Origin>& top_frame_origin,
3064     const GURL& script_url,
3065     content::BrowserContext* context) {
3066   DCHECK(context);
3067   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3068   GURL first_party_url = top_frame_origin ? top_frame_origin->GetURL() : GURL();
3069
3070 #if BUILDFLAG(ENABLE_EXTENSIONS)
3071   // Check if this is an extension-related service worker, and, if so, if it's
3072   // allowed (this can return false if, e.g., the extension is disabled).
3073   // If it's not allowed, return immediately. We deliberately do *not* report
3074   // to the PageSpecificContentSettings, since the service worker is blocked
3075   // because of the extension, rather than because of the user's content
3076   // settings.
3077   if (!ChromeContentBrowserClientExtensionsPart::AllowServiceWorker(
3078           scope, first_party_url, script_url, context)) {
3079     return content::AllowServiceWorkerResult::No();
3080   }
3081 #endif
3082
3083   Profile* profile = Profile::FromBrowserContext(context);
3084   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3085       CookieSettingsFactory::GetForProfile(profile);
3086   return embedder_support::AllowServiceWorker(
3087       scope, site_for_cookies, top_frame_origin, cookie_settings.get(),
3088       HostContentSettingsMapFactory::GetForProfile(profile));
3089 }
3090
3091 bool ChromeContentBrowserClient::MayDeleteServiceWorkerRegistration(
3092     const GURL& scope,
3093     content::BrowserContext* browser_context) {
3094   DCHECK(browser_context);
3095   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3096
3097 #if BUILDFLAG(ENABLE_EXTENSIONS)
3098   if (!ChromeContentBrowserClientExtensionsPart::
3099           MayDeleteServiceWorkerRegistration(scope, browser_context)) {
3100     return false;
3101   }
3102 #endif
3103
3104   return true;
3105 }
3106
3107 bool ChromeContentBrowserClient::ShouldTryToUpdateServiceWorkerRegistration(
3108     const GURL& scope,
3109     content::BrowserContext* browser_context) {
3110   DCHECK(browser_context);
3111   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3112
3113 #if BUILDFLAG(ENABLE_EXTENSIONS)
3114   if (!ChromeContentBrowserClientExtensionsPart::
3115           ShouldTryToUpdateServiceWorkerRegistration(scope, browser_context)) {
3116     return false;
3117   }
3118 #endif
3119
3120   return true;
3121 }
3122
3123 void ChromeContentBrowserClient::
3124     UpdateEnabledBlinkRuntimeFeaturesInIsolatedWorker(
3125         content::BrowserContext* context,
3126         const GURL& script_url,
3127         std::vector<std::string>& out_forced_enabled_runtime_features) {
3128   DCHECK(context);
3129
3130 #if BUILDFLAG(IS_CHROMEOS_ASH)
3131   auto* profile = Profile::FromBrowserContext(context);
3132   if (!ash::IsSystemExtensionsEnabled(profile))
3133     return;
3134
3135   ash::SystemExtensionsProvider::Get(profile)
3136       .UpdateEnabledBlinkRuntimeFeaturesInIsolatedWorker(
3137           script_url, out_forced_enabled_runtime_features);
3138 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
3139 }
3140
3141 bool ChromeContentBrowserClient::AllowSharedWorker(
3142     const GURL& worker_url,
3143     const net::SiteForCookies& site_for_cookies,
3144     const absl::optional<url::Origin>& top_frame_origin,
3145     const std::string& name,
3146     const blink::StorageKey& storage_key,
3147     content::BrowserContext* context,
3148     int render_process_id,
3149     int render_frame_id) {
3150   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3151
3152   // Check if cookies are allowed.
3153   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3154       CookieSettingsFactory::GetForProfile(
3155           Profile::FromBrowserContext(context));
3156   return embedder_support::AllowSharedWorker(
3157       worker_url, site_for_cookies, top_frame_origin, name, storage_key,
3158       render_process_id, render_frame_id, cookie_settings.get());
3159 }
3160
3161 bool ChromeContentBrowserClient::DoesSchemeAllowCrossOriginSharedWorker(
3162     const std::string& scheme) {
3163 #if BUILDFLAG(ENABLE_EXTENSIONS)
3164   // Extensions are allowed to start cross-origin shared workers.
3165   if (scheme == extensions::kExtensionScheme)
3166     return true;
3167 #endif
3168
3169   return false;
3170 }
3171
3172 bool ChromeContentBrowserClient::AllowSignedExchange(
3173     content::BrowserContext* browser_context) {
3174   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3175   Profile* profile = Profile::FromBrowserContext(browser_context);
3176   return profile->GetPrefs()->GetBoolean(prefs::kSignedHTTPExchangeEnabled);
3177 }
3178
3179 bool ChromeContentBrowserClient::AllowCompressionDictionaryTransport(
3180     content::BrowserContext* browser_context) {
3181   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3182   Profile* profile = Profile::FromBrowserContext(browser_context);
3183   return profile->GetPrefs()->GetBoolean(
3184       prefs::kCompressionDictionaryTransportEnabled);
3185 }
3186
3187 void ChromeContentBrowserClient::RequestFilesAccess(
3188     const std::vector<base::FilePath>& files,
3189     const GURL& destination_url,
3190     base::OnceCallback<void(file_access::ScopedFileAccess)>
3191         continuation_callback) {
3192   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3193 #if BUILDFLAG(IS_CHROMEOS)
3194   auto* delegate = policy::DlpScopedFileAccessDelegate::Get();
3195   if (delegate) {
3196     delegate->RequestFilesAccess(files, destination_url,
3197                                  std::move(continuation_callback));
3198   } else {
3199     std::move(continuation_callback)
3200         .Run(file_access::ScopedFileAccess::Allowed());
3201   }
3202 #else
3203   std::move(continuation_callback)
3204       .Run(file_access::ScopedFileAccess::Allowed());
3205 #endif
3206 }
3207
3208 void ChromeContentBrowserClient::AllowWorkerFileSystem(
3209     const GURL& url,
3210     content::BrowserContext* browser_context,
3211     const std::vector<content::GlobalRenderFrameHostId>& render_frames,
3212     base::OnceCallback<void(bool)> callback) {
3213   // An empty list is passed for render_frames here since we manually notify
3214   // PageSpecificContentSettings that the file system was accessed below.
3215   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3216       CookieSettingsFactory::GetForProfile(
3217           Profile::FromBrowserContext(browser_context));
3218   bool allow =
3219       embedder_support::AllowWorkerFileSystem(url, {}, cookie_settings.get());
3220 #if BUILDFLAG(ENABLE_EXTENSIONS)
3221   GuestPermissionRequestHelper(url, render_frames, std::move(callback), allow);
3222 #else
3223   FileSystemAccessed(url, render_frames, std::move(callback), allow);
3224 #endif
3225 }
3226
3227 #if BUILDFLAG(ENABLE_EXTENSIONS)
3228 void ChromeContentBrowserClient::GuestPermissionRequestHelper(
3229     const GURL& url,
3230     const std::vector<content::GlobalRenderFrameHostId>& render_frames,
3231     base::OnceCallback<void(bool)> callback,
3232     bool allow) {
3233   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3234   std::map<int, int> process_map;
3235   bool has_web_view_guest = false;
3236   // Record access to file system for potential display in UI.
3237   for (const auto& it : render_frames) {
3238     if (process_map.find(it.child_id) != process_map.end())
3239       continue;
3240
3241     process_map.insert(std::pair<int, int>(it.child_id, it.frame_routing_id));
3242
3243     if (extensions::WebViewRendererState::GetInstance()->IsGuest(it.child_id))
3244       has_web_view_guest = true;
3245   }
3246   if (!has_web_view_guest) {
3247     FileSystemAccessed(url, render_frames, std::move(callback), allow);
3248     return;
3249   }
3250   DCHECK_EQ(1U, process_map.size());
3251   std::map<int, int>::const_iterator it = process_map.begin();
3252
3253   extensions::WebViewPermissionHelper* web_view_permission_helper =
3254       extensions::WebViewPermissionHelper::FromRenderFrameHostId(
3255           content::GlobalRenderFrameHostId(it->first, it->second));
3256   web_view_permission_helper->RequestFileSystemPermission(
3257       url, allow,
3258       base::BindOnce(&ChromeContentBrowserClient::FileSystemAccessed,
3259                      weak_factory_.GetWeakPtr(), url, render_frames,
3260                      std::move(callback)));
3261 }
3262 #endif
3263
3264 void ChromeContentBrowserClient::FileSystemAccessed(
3265     const GURL& url,
3266     const std::vector<content::GlobalRenderFrameHostId>& render_frames,
3267     base::OnceCallback<void(bool)> callback,
3268     bool allow) {
3269   // Record access to file system for potential display in UI.
3270   for (const auto& it : render_frames) {
3271     auto* rfh = content::RenderFrameHost::FromID(it);
3272     if (!rfh) {
3273       continue;
3274     }
3275     content_settings::PageSpecificContentSettings::StorageAccessed(
3276         content_settings::mojom::ContentSettingsManager::StorageType::
3277             FILE_SYSTEM,
3278         it.child_id, it.frame_routing_id, rfh->GetStorageKey(), !allow);
3279   }
3280   std::move(callback).Run(allow);
3281 }
3282
3283 bool ChromeContentBrowserClient::AllowWorkerIndexedDB(
3284     const GURL& url,
3285     content::BrowserContext* browser_context,
3286     const std::vector<content::GlobalRenderFrameHostId>& render_frames) {
3287   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3288       CookieSettingsFactory::GetForProfile(
3289           Profile::FromBrowserContext(browser_context));
3290   return embedder_support::AllowWorkerIndexedDB(url, render_frames,
3291                                                 cookie_settings.get());
3292 }
3293
3294 bool ChromeContentBrowserClient::AllowWorkerCacheStorage(
3295     const GURL& url,
3296     content::BrowserContext* browser_context,
3297     const std::vector<content::GlobalRenderFrameHostId>& render_frames) {
3298   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3299       CookieSettingsFactory::GetForProfile(
3300           Profile::FromBrowserContext(browser_context));
3301   return embedder_support::AllowWorkerCacheStorage(url, render_frames,
3302                                                    cookie_settings.get());
3303 }
3304
3305 bool ChromeContentBrowserClient::AllowWorkerWebLocks(
3306     const GURL& url,
3307     content::BrowserContext* browser_context,
3308     const std::vector<content::GlobalRenderFrameHostId>& render_frames) {
3309   scoped_refptr<content_settings::CookieSettings> cookie_settings =
3310       CookieSettingsFactory::GetForProfile(
3311           Profile::FromBrowserContext(browser_context));
3312   return embedder_support::AllowWorkerWebLocks(url, cookie_settings.get());
3313 }
3314
3315 ChromeContentBrowserClient::AllowWebBluetoothResult
3316 ChromeContentBrowserClient::AllowWebBluetooth(
3317     content::BrowserContext* browser_context,
3318     const url::Origin& requesting_origin,
3319     const url::Origin& embedding_origin) {
3320   // TODO(crbug.com/598890): Don't disable if
3321   // base::CommandLine::ForCurrentProcess()->
3322   // HasSwitch(switches::kEnableWebBluetooth) is true.
3323   if (base::GetFieldTrialParamValue(
3324           permissions::PermissionContextBase::kPermissionsKillSwitchFieldStudy,
3325           "Bluetooth") ==
3326       permissions::PermissionContextBase::kPermissionsKillSwitchBlockedValue) {
3327     // The kill switch is enabled for this permission. Block requests.
3328     return AllowWebBluetoothResult::BLOCK_GLOBALLY_DISABLED;
3329   }
3330
3331   const HostContentSettingsMap* const content_settings =
3332       HostContentSettingsMapFactory::GetForProfile(
3333           Profile::FromBrowserContext(browser_context));
3334
3335   if (content_settings->GetContentSetting(
3336           requesting_origin.GetURL(), embedding_origin.GetURL(),
3337           ContentSettingsType::BLUETOOTH_GUARD) == CONTENT_SETTING_BLOCK) {
3338     return AllowWebBluetoothResult::BLOCK_POLICY;
3339   }
3340   return AllowWebBluetoothResult::ALLOW;
3341 }
3342
3343 std::string ChromeContentBrowserClient::GetWebBluetoothBlocklist() {
3344   return base::GetFieldTrialParamValue("WebBluetoothBlocklist",
3345                                        "blocklist_additions");
3346 }
3347
3348 bool ChromeContentBrowserClient::IsInterestGroupAPIAllowed(
3349     content::RenderFrameHost* render_frame_host,
3350     InterestGroupApiOperation operation,
3351     const url::Origin& top_frame_origin,
3352     const url::Origin& api_origin) {
3353   Profile* profile =
3354       Profile::FromBrowserContext(render_frame_host->GetBrowserContext());
3355   auto* privacy_sandbox_settings =
3356       PrivacySandboxSettingsFactory::GetForProfile(profile);
3357   DCHECK(privacy_sandbox_settings);
3358
3359   bool allowed = privacy_sandbox_settings->IsFledgeAllowed(
3360       top_frame_origin, api_origin, operation, render_frame_host);
3361
3362   if (operation == InterestGroupApiOperation::kJoin) {
3363     content_settings::PageSpecificContentSettings::InterestGroupJoined(
3364         render_frame_host, api_origin, !allowed);
3365     content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
3366         render_frame_host,
3367         content::InterestGroupManager::InterestGroupDataKey{api_origin,
3368                                                             top_frame_origin},
3369         BrowsingDataModel::StorageType::kInterestGroup, !allowed);
3370   }
3371
3372   return allowed;
3373 }
3374
3375 bool ChromeContentBrowserClient::IsPrivacySandboxReportingDestinationAttested(
3376     content::BrowserContext* browser_context,
3377     const url::Origin& destination_origin,
3378     content::PrivacySandboxInvokingAPI invoking_api) {
3379   Profile* profile = Profile::FromBrowserContext(browser_context);
3380   auto* privacy_sandbox_settings =
3381       PrivacySandboxSettingsFactory::GetForProfile(profile);
3382   DCHECK(privacy_sandbox_settings);
3383
3384   privacy_sandbox::PrivacySandboxAttestationsGatedAPI gated_api;
3385   switch (invoking_api) {
3386     case content::PrivacySandboxInvokingAPI::kProtectedAudience:
3387       gated_api = privacy_sandbox::PrivacySandboxAttestationsGatedAPI::
3388           kProtectedAudience;
3389       break;
3390     case content::PrivacySandboxInvokingAPI::kSharedStorage:
3391       gated_api =
3392           privacy_sandbox::PrivacySandboxAttestationsGatedAPI::kSharedStorage;
3393       break;
3394   }
3395
3396   return privacy_sandbox_settings->IsEventReportingDestinationAttested(
3397       destination_origin, gated_api);
3398 }
3399
3400 void ChromeContentBrowserClient::OnAuctionComplete(
3401     content::RenderFrameHost* render_frame_host,
3402     content::InterestGroupManager::InterestGroupDataKey winner_data_key) {
3403   content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
3404       render_frame_host, winner_data_key,
3405       BrowsingDataModel::StorageType::kInterestGroup,
3406       /*blocked=*/false);
3407 }
3408
3409 bool ChromeContentBrowserClient::IsAttributionReportingOperationAllowed(
3410     content::BrowserContext* browser_context,
3411     AttributionReportingOperation operation,
3412     content::RenderFrameHost* rfh,
3413     const url::Origin* source_origin,
3414     const url::Origin* destination_origin,
3415     const url::Origin* reporting_origin) {
3416   Profile* profile = Profile::FromBrowserContext(browser_context);
3417
3418   auto* privacy_sandbox_settings =
3419       PrivacySandboxSettingsFactory::GetForProfile(profile);
3420   if (!privacy_sandbox_settings)
3421     return false;
3422
3423   switch (operation) {
3424     case AttributionReportingOperation::kSource:
3425     case AttributionReportingOperation::kOsSource: {
3426       DCHECK(source_origin);
3427       DCHECK(reporting_origin);
3428       bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed(
3429           *source_origin, *reporting_origin, rfh);
3430       if (rfh) {
3431         content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
3432             rfh, content::AttributionDataModel::DataKey(*reporting_origin),
3433             BrowsingDataModel::StorageType::kAttributionReporting,
3434             /*blocked=*/!allowed);
3435       }
3436       return allowed;
3437     }
3438     case AttributionReportingOperation::kSourceVerboseDebugReport:
3439     case AttributionReportingOperation::kOsSourceVerboseDebugReport:
3440       DCHECK(source_origin);
3441       DCHECK(reporting_origin);
3442       return privacy_sandbox_settings->IsAttributionReportingAllowed(
3443           *source_origin, *reporting_origin, rfh);
3444     case AttributionReportingOperation::kTrigger:
3445     case AttributionReportingOperation::kOsTrigger: {
3446       DCHECK(destination_origin);
3447       DCHECK(reporting_origin);
3448       bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed(
3449           *destination_origin, *reporting_origin, rfh);
3450       if (rfh) {
3451         content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
3452             rfh, content::AttributionDataModel::DataKey(*reporting_origin),
3453             BrowsingDataModel::StorageType::kAttributionReporting,
3454             /*blocked=*/!allowed);
3455       }
3456       return allowed;
3457     }
3458     case AttributionReportingOperation::kTriggerVerboseDebugReport:
3459     case AttributionReportingOperation::kOsTriggerVerboseDebugReport:
3460       DCHECK(destination_origin);
3461       DCHECK(reporting_origin);
3462       return privacy_sandbox_settings->IsAttributionReportingAllowed(
3463           *destination_origin, *reporting_origin, rfh);
3464     case AttributionReportingOperation::kReport:
3465       DCHECK(source_origin);
3466       DCHECK(destination_origin);
3467       DCHECK(reporting_origin);
3468       return privacy_sandbox_settings->MaySendAttributionReport(
3469           *source_origin, *destination_origin, *reporting_origin, rfh);
3470     case AttributionReportingOperation::kSourceTransitionalDebugReporting:
3471     case AttributionReportingOperation::kOsSourceTransitionalDebugReporting:
3472       DCHECK(source_origin);
3473       DCHECK(reporting_origin);
3474       return privacy_sandbox_settings
3475           ->IsAttributionReportingTransitionalDebuggingAllowed(
3476               *source_origin, *reporting_origin);
3477     case AttributionReportingOperation::kTriggerTransitionalDebugReporting:
3478     case AttributionReportingOperation::kOsTriggerTransitionalDebugReporting:
3479       DCHECK(destination_origin);
3480       DCHECK(reporting_origin);
3481       return privacy_sandbox_settings
3482           ->IsAttributionReportingTransitionalDebuggingAllowed(
3483               *destination_origin, *reporting_origin);
3484     case AttributionReportingOperation::kAny:
3485       return privacy_sandbox_settings->IsAttributionReportingEverAllowed();
3486   }
3487 }
3488
3489 bool ChromeContentBrowserClient::IsSharedStorageAllowed(
3490     content::BrowserContext* browser_context,
3491     content::RenderFrameHost* rfh,
3492     const url::Origin& top_frame_origin,
3493     const url::Origin& accessing_origin) {
3494   Profile* profile = Profile::FromBrowserContext(browser_context);
3495   auto* privacy_sandbox_settings =
3496       PrivacySandboxSettingsFactory::GetForProfile(profile);
3497   DCHECK(privacy_sandbox_settings);
3498   bool allowed = privacy_sandbox_settings->IsSharedStorageAllowed(
3499       top_frame_origin, accessing_origin, rfh);
3500   if (rfh) {
3501     content_settings::PageSpecificContentSettings::BrowsingDataAccessed(
3502         rfh, blink::StorageKey::CreateFirstParty(accessing_origin),
3503         BrowsingDataModel::StorageType::kSharedStorage, !allowed);
3504   }
3505   return allowed;
3506 }
3507
3508 bool ChromeContentBrowserClient::IsSharedStorageSelectURLAllowed(
3509     content::BrowserContext* browser_context,
3510     const url::Origin& top_frame_origin,
3511     const url::Origin& accessing_origin) {
3512   Profile* profile = Profile::FromBrowserContext(browser_context);
3513   auto* privacy_sandbox_settings =
3514       PrivacySandboxSettingsFactory::GetForProfile(profile);
3515   DCHECK(privacy_sandbox_settings);
3516   return privacy_sandbox_settings->IsSharedStorageSelectURLAllowed(
3517       top_frame_origin, accessing_origin);
3518 }
3519
3520 bool ChromeContentBrowserClient::IsPrivateAggregationAllowed(
3521     content::BrowserContext* browser_context,
3522     const url::Origin& top_frame_origin,
3523     const url::Origin& reporting_origin) {
3524   Profile* profile = Profile::FromBrowserContext(browser_context);
3525   auto* privacy_sandbox_settings =
3526       PrivacySandboxSettingsFactory::GetForProfile(profile);
3527   DCHECK(privacy_sandbox_settings);
3528
3529   return privacy_sandbox_settings->IsPrivateAggregationAllowed(
3530       top_frame_origin, reporting_origin);
3531 }
3532
3533 bool ChromeContentBrowserClient::IsPrivateAggregationDebugModeAllowed(
3534     content::BrowserContext* browser_context,
3535     const url::Origin& top_frame_origin,
3536     const url::Origin& reporting_origin) {
3537   Profile* profile = Profile::FromBrowserContext(browser_context);
3538   auto* privacy_sandbox_settings =
3539       PrivacySandboxSettingsFactory::GetForProfile(profile);
3540   DCHECK(privacy_sandbox_settings);
3541
3542   return privacy_sandbox_settings->IsPrivateAggregationDebugModeAllowed(
3543       top_frame_origin, reporting_origin);
3544 }
3545
3546 bool ChromeContentBrowserClient::IsCookieDeprecationLabelAllowed(
3547     content::BrowserContext* browser_context) {
3548   Profile* profile = Profile::FromBrowserContext(browser_context);
3549
3550   auto* privacy_sandbox_settings =
3551       PrivacySandboxSettingsFactory::GetForProfile(profile);
3552   if (!privacy_sandbox_settings) {
3553     return false;
3554   }
3555   return privacy_sandbox_settings->IsCookieDeprecationLabelAllowed();
3556 }
3557
3558 bool ChromeContentBrowserClient::IsCookieDeprecationLabelAllowedForContext(
3559     content::BrowserContext* browser_context,
3560     const url::Origin& top_frame_origin,
3561     const url::Origin& context_origin) {
3562   Profile* profile = Profile::FromBrowserContext(browser_context);
3563
3564   auto* privacy_sandbox_settings =
3565       PrivacySandboxSettingsFactory::GetForProfile(profile);
3566   DCHECK(privacy_sandbox_settings);
3567   return privacy_sandbox_settings->IsCookieDeprecationLabelAllowedForContext(
3568       top_frame_origin, context_origin);
3569 }
3570
3571 #if BUILDFLAG(IS_CHROMEOS)
3572 void ChromeContentBrowserClient::OnTrustAnchorUsed(
3573     content::BrowserContext* browser_context) {
3574   policy::PolicyCertService* service =
3575       policy::PolicyCertServiceFactory::GetForProfile(
3576           Profile::FromBrowserContext(browser_context));
3577   if (!service) {
3578     NOTREACHED();
3579     return;
3580   }
3581   service->SetUsedPolicyCertificates();
3582 }
3583 #endif
3584
3585 bool ChromeContentBrowserClient::CanSendSCTAuditingReport(
3586     content::BrowserContext* browser_context) {
3587   return SCTReportingService::CanSendSCTAuditingReport();
3588 }
3589
3590 void ChromeContentBrowserClient::OnNewSCTAuditingReportSent(
3591     content::BrowserContext* browser_context) {
3592   SCTReportingService::OnNewSCTAuditingReportSent();
3593 }
3594
3595 scoped_refptr<network::SharedURLLoaderFactory>
3596 ChromeContentBrowserClient::GetSystemSharedURLLoaderFactory() {
3597   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
3598          !BrowserThread::IsThreadInitialized(BrowserThread::UI));
3599
3600   if (!SystemNetworkContextManager::GetInstance())
3601     return nullptr;
3602
3603   return SystemNetworkContextManager::GetInstance()
3604       ->GetSharedURLLoaderFactory();
3605 }
3606
3607 network::mojom::NetworkContext*
3608 ChromeContentBrowserClient::GetSystemNetworkContext() {
3609   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3610   DCHECK(g_browser_process->system_network_context_manager());
3611   return g_browser_process->system_network_context_manager()->GetContext();
3612 }
3613
3614 std::string ChromeContentBrowserClient::GetGeolocationApiKey() {
3615   return google_apis::GetAPIKey();
3616 }
3617
3618 #if BUILDFLAG(IS_MAC)
3619 device::GeolocationManager*
3620 ChromeContentBrowserClient::GetGeolocationManager() {
3621   return device::GeolocationManager::GetInstance();
3622 }
3623 #endif
3624
3625 #if BUILDFLAG(IS_ANDROID)
3626 bool ChromeContentBrowserClient::ShouldUseGmsCoreGeolocationProvider() {
3627   // Indicate that Chrome uses the GMS core location provider.
3628   return true;
3629 }
3630 #endif
3631
3632 content::GeneratedCodeCacheSettings
3633 ChromeContentBrowserClient::GetGeneratedCodeCacheSettings(
3634     content::BrowserContext* context) {
3635   base::FilePath cache_path;
3636   chrome::GetUserCacheDirectory(context->GetPath(), &cache_path);
3637   // If we pass 0 for size, disk_cache will pick a default size using the
3638   // heuristics based on available disk size. These are implemented in
3639   // disk_cache::PreferredCacheSize in net/disk_cache/cache_util.cc.
3640   int64_t size_in_bytes = 0;
3641   DCHECK(g_browser_process);
3642   PrefService* local_state = g_browser_process->local_state();
3643   if (local_state) {
3644     size_in_bytes = local_state->GetInteger(prefs::kDiskCacheSize);
3645     base::FilePath disk_cache_dir =
3646         local_state->GetFilePath(prefs::kDiskCacheDir);
3647     if (!disk_cache_dir.empty())
3648       cache_path = disk_cache_dir.Append(cache_path.BaseName());
3649   }
3650   return content::GeneratedCodeCacheSettings(true, size_in_bytes, cache_path);
3651 }
3652
3653 void ChromeContentBrowserClient::AllowCertificateError(
3654     content::WebContents* web_contents,
3655     int cert_error,
3656     const net::SSLInfo& ssl_info,
3657     const GURL& request_url,
3658     bool is_primary_main_frame_request,
3659     bool strict_enforcement,
3660     base::OnceCallback<void(content::CertificateRequestResultType)> callback) {
3661   DCHECK(web_contents);
3662   if (!is_primary_main_frame_request) {
3663     // A sub-resource has a certificate error. The user doesn't really
3664     // have a context for making the right decision, so block the
3665     // request hard, without an info bar to allow showing the insecure
3666     // content.
3667     if (!callback.is_null())
3668       std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
3669     return;
3670   }
3671
3672   // If the tab is being no-state prefetched, cancel the prefetcher and the
3673   // request.
3674   prerender::NoStatePrefetchContents* no_state_prefetch_contents =
3675       prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
3676           web_contents);
3677   if (no_state_prefetch_contents) {
3678     no_state_prefetch_contents->Destroy(prerender::FINAL_STATUS_SSL_ERROR);
3679     if (!callback.is_null()) {
3680       std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL);
3681     }
3682     return;
3683   }
3684
3685   std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY);
3686   return;
3687 }
3688
3689 #if !BUILDFLAG(IS_ANDROID)
3690 bool ChromeContentBrowserClient::ShouldDenyRequestOnCertificateError(
3691     const GURL main_page_url) {
3692   // Desktop Reader Mode pages should never load resources with certificate
3693   // errors. Desktop Reader Mode is more strict about security than Reader Mode
3694   // on Android: the desktop version has its own security indicator and
3695   // is not downgraded to a WARNING, whereas Android will show "Not secure"
3696   // in the omnibox (for low-end devices which show the omnibox on Reader Mode
3697   // pages).
3698   return main_page_url.SchemeIs(dom_distiller::kDomDistillerScheme);
3699 }
3700 #endif
3701
3702 namespace {
3703
3704 #if !BUILDFLAG(IS_ANDROID)
3705 blink::mojom::PreferredColorScheme ToBlinkPreferredColorScheme(
3706     ui::NativeTheme::PreferredColorScheme native_theme_scheme) {
3707   switch (native_theme_scheme) {
3708     case ui::NativeTheme::PreferredColorScheme::kDark:
3709       return blink::mojom::PreferredColorScheme::kDark;
3710     case ui::NativeTheme::PreferredColorScheme::kLight:
3711       return blink::mojom::PreferredColorScheme::kLight;
3712   }
3713 }
3714 #endif  // !BUILDFLAG(IS_ANDROID)
3715
3716 // Returns true if preferred color scheme is modified based on at least one of
3717 // the following -
3718 // |url| - Last committed url.
3719 // |web_contents| - For Android based on IsNightModeEnabled().
3720 // |native_theme| - For other platforms based on native theme scheme.
3721 bool UpdatePreferredColorScheme(WebPreferences* web_prefs,
3722                                 const GURL& url,
3723                                 WebContents* web_contents,
3724                                 const ui::NativeTheme* native_theme) {
3725   auto old_preferred_color_scheme = web_prefs->preferred_color_scheme;
3726
3727 #if BUILDFLAG(IS_ANDROID)
3728   auto* delegate = TabAndroid::FromWebContents(web_contents)
3729                        ? static_cast<android::TabWebContentsDelegateAndroid*>(
3730                              web_contents->GetDelegate())
3731                        : nullptr;
3732   if (delegate) {
3733     web_prefs->preferred_color_scheme =
3734         delegate->IsNightModeEnabled()
3735             ? blink::mojom::PreferredColorScheme::kDark
3736             : blink::mojom::PreferredColorScheme::kLight;
3737   }
3738 #else
3739   // Update based on native theme scheme.
3740   web_prefs->preferred_color_scheme =
3741       ToBlinkPreferredColorScheme(native_theme->GetPreferredColorScheme());
3742 #endif  // BUILDFLAG(IS_ANDROID)
3743
3744   // Reauth WebUI doesn't support dark mode yet because it shares the dialog
3745   // with GAIA web contents that is not correctly themed.
3746   const bool force_light =
3747       url.SchemeIs(content::kChromeUIScheme) &&
3748       url.host_piece() == chrome::kChromeUISigninReauthHost;
3749
3750   if (force_light) {
3751     web_prefs->preferred_color_scheme =
3752         blink::mojom::PreferredColorScheme::kLight;
3753   } else if (url.SchemeIs(content::kChromeUIScheme)) {
3754     // If color scheme is not forced, WebUI should track the color mode of the
3755     // ColorProvider associated with `web_contents`.
3756     web_prefs->preferred_color_scheme =
3757         web_contents->GetColorMode() == ui::ColorProviderKey::ColorMode::kLight
3758             ? blink::mojom::PreferredColorScheme::kLight
3759             : blink::mojom::PreferredColorScheme::kDark;
3760   }
3761
3762   return old_preferred_color_scheme != web_prefs->preferred_color_scheme;
3763 }
3764
3765 // Returns whether the user can be prompted to select a client certificate after
3766 // no certificate got auto-selected.
3767 bool CanPromptWithNonmatchingCertificates(const Profile* profile) {
3768 #if BUILDFLAG(IS_CHROMEOS_ASH)
3769   if (ash::ProfileHelper::IsSigninProfile(profile) ||
3770       ash::ProfileHelper::IsLockScreenProfile(profile) ||
3771       ash::ProfileHelper::IsLockScreenAppProfile(profile)) {
3772     // On non-regular profiles (e.g. sign-in profile or lock-screen profile),
3773     // never show certificate selection to the user. A client certificate is an
3774     // identifier that can be stable for a long time, so only the administrator
3775     // is allowed to decide which endpoints should see it.
3776     // This also returns false for the lock screen app profile which can
3777     // not use client certificates anyway - to be on the safe side in case
3778     // support for client certificates is added later.
3779     return false;
3780   }
3781 #endif
3782   return true;
3783 }
3784
3785 // Returns whether the user should be prompted to select a client certificate
3786 // when multiple certificates got auto-selected.
3787 bool ShouldPromptOnMultipleMatchingCertificates(const Profile* profile) {
3788   const PrefService* const prefs = profile->GetPrefs();
3789   DCHECK(prefs);
3790   const PrefService::Preference* pref =
3791       prefs->FindPreference(prefs::kPromptOnMultipleMatchingCertificates);
3792   if (pref && pref->IsManaged() && pref->GetValue()->is_bool())
3793     return pref->GetValue()->GetBool();
3794   return false;
3795 }
3796
3797 }  // namespace
3798
3799 base::OnceClosure ChromeContentBrowserClient::SelectClientCertificate(
3800     content::BrowserContext* browser_context,
3801     content::WebContents* web_contents,
3802     net::SSLCertRequestInfo* cert_request_info,
3803     net::ClientCertIdentityList client_certs,
3804     std::unique_ptr<content::ClientCertificateDelegate> delegate) {
3805   prerender::NoStatePrefetchContents* no_state_prefetch_contents =
3806       web_contents
3807           ? prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
3808                 web_contents)
3809           : nullptr;
3810   if (no_state_prefetch_contents) {
3811     no_state_prefetch_contents->Destroy(
3812         prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED);
3813     return base::OnceClosure();
3814   }
3815
3816   Profile* profile = Profile::FromBrowserContext(browser_context);
3817 #if BUILDFLAG(IS_CHROMEOS_ASH)
3818   // On the sign-in or lock screen profile, only allow client certs in the
3819   // context of the sign-in frame.
3820   // Note that this is explicitly not happening for the lock screen app profile
3821   // which does not support a gaia / SAML IdP sign-in frame.
3822   if (ash::ProfileHelper::IsSigninProfile(profile) ||
3823       ash::ProfileHelper::IsLockScreenProfile(profile)) {
3824     const char* profile_name = ash::ProfileHelper::IsSigninProfile(profile)
3825                                    ? "sign-in"
3826                                    : "lock screen";
3827
3828     // TODO(b/290262513): See also comment below -- if the continuation should
3829     // be a cancelation, this check is unnecessary and we can just fall-through
3830     // without treating signin profiles differently for service workers.
3831     if (!web_contents) {
3832       LOG(WARNING) << "Client cert requested in " << profile_name
3833                    << " profile from service worker. This is not supported.";
3834       // Return without calling anything on `delegate`. This results in the
3835       // `delegate` being deleted, which implicitly calls to cancel the request.
3836       return base::OnceClosure();
3837     }
3838
3839     content::StoragePartition* storage_partition =
3840         profile->GetStoragePartition(web_contents->GetSiteInstance());
3841     auto* signin_partition_manager =
3842         ash::login::SigninPartitionManager::Factory::GetForBrowserContext(
3843             profile);
3844     if (!signin_partition_manager->IsCurrentSigninStoragePartition(
3845             storage_partition)) {
3846       LOG(WARNING) << "Client cert requested in " << profile_name
3847                    << " profile in wrong context.";
3848       // Continue without client certificate. We do this to mimic the case of no
3849       // client certificate being present in the profile's certificate store.
3850       // TODO(b/290262513): Should this be a cancel? Selecting "no certificate"
3851       // is a sticky decision.
3852       delegate->ContinueWithCertificate(nullptr, nullptr);
3853       return base::OnceClosure();
3854     }
3855     VLOG(1) << "Client cert requested in " << profile_name << " profile.";
3856   }
3857 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
3858
3859   GURL requesting_url = chrome::enterprise_util::GetRequestingUrl(
3860       cert_request_info->host_and_port);
3861   DCHECK(requesting_url.is_valid()) << "Invalid URL string: " << requesting_url;
3862
3863   net::ClientCertIdentityList matching_certificates, nonmatching_certificates;
3864   chrome::enterprise_util::AutoSelectCertificates(
3865       profile, requesting_url, std::move(client_certs), &matching_certificates,
3866       &nonmatching_certificates);
3867
3868   if (matching_certificates.size() == 1 ||
3869       (matching_certificates.size() > 1 &&
3870        !ShouldPromptOnMultipleMatchingCertificates(profile))) {
3871     // Always take the first certificate, even if multiple ones matched -
3872     // there's no other criteria available for tie-breaking, and user prompts
3873     // aren't enabled.
3874     std::unique_ptr<net::ClientCertIdentity> auto_selected_identity =
3875         std::move(matching_certificates[0]);
3876     // The callback will own |auto_selected_identity| and |delegate|, keeping
3877     // them alive until after ContinueWithCertificate is called.
3878     scoped_refptr<net::X509Certificate> cert =
3879         auto_selected_identity->certificate();
3880     net::ClientCertIdentity::SelfOwningAcquirePrivateKey(
3881         std::move(auto_selected_identity),
3882         base::BindOnce(
3883             &content::ClientCertificateDelegate::ContinueWithCertificate,
3884             std::move(delegate), std::move(cert)));
3885     LogClientAuthResult(ClientCertSelectionResult::kAutoSelect);
3886     return base::OnceClosure();
3887   }
3888
3889   // At this point, we're going to either a) continue without a valid
3890   // certificate (if we're not allowed to prompt) or b) show the picker for the
3891   // user to select a valid cert. Only do this if the requestor has a valid
3892   // WebContents. In the case of a), we want to preserve consistency (so that
3893   // requests always fail or succeed across different platforms and contexts),
3894   // and for b), we don't want to pop up UI for background requests like
3895   // service workers (where there's no visual context to the user).
3896   if (!web_contents) {
3897     // Return without calling anything on `delegate`. This results in the
3898     // `delegate` being deleted, which implicitly calls to cancel the request.
3899     return base::OnceClosure();
3900   }
3901
3902   if (matching_certificates.empty() &&
3903       !CanPromptWithNonmatchingCertificates(profile)) {
3904     LOG(WARNING) << "No client cert matched by policy and user selection is "
3905                     "not allowed.";
3906     LogClientAuthResult(ClientCertSelectionResult::kNoSelectionAllowed);
3907     // Continue without client certificate. We do this to mimic the case of no
3908     // client certificate being present in the profile's certificate store.
3909     delegate->ContinueWithCertificate(nullptr, nullptr);
3910     return base::OnceClosure();
3911   }
3912
3913   // Note: It can happen that both lists are empty, still the selector needs to
3914   // be shown - see the comment in SSLClientAuthHandler::DidGetClientCerts()
3915   // about platforms not having a client cert store.
3916   net::ClientCertIdentityList client_cert_choices =
3917       !matching_certificates.empty() ? std::move(matching_certificates)
3918                                      : std::move(nonmatching_certificates);
3919
3920   return chrome::ShowSSLClientCertificateSelector(
3921       web_contents, cert_request_info, std::move(client_cert_choices),
3922       std::move(delegate));
3923 }
3924
3925 content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() {
3926   return MediaCaptureDevicesDispatcher::GetInstance();
3927 }
3928
3929 content::FeatureObserverClient*
3930 ChromeContentBrowserClient::GetFeatureObserverClient() {
3931   return ChromeBrowserMainExtraPartsPerformanceManager::GetInstance()
3932       ->GetFeatureObserverClient();
3933 }
3934
3935 bool ChromeContentBrowserClient::CanCreateWindow(
3936     RenderFrameHost* opener,
3937     const GURL& opener_url,
3938     const GURL& opener_top_level_frame_url,
3939     const url::Origin& source_origin,
3940     content::mojom::WindowContainerType container_type,
3941     const GURL& target_url,
3942     const content::Referrer& referrer,
3943     const std::string& frame_name,
3944     WindowOpenDisposition disposition,
3945     const blink::mojom::WindowFeatures& features,
3946     bool user_gesture,
3947     bool opener_suppressed,
3948     bool* no_javascript_access) {
3949   DCHECK_CURRENTLY_ON(BrowserThread::UI);
3950   DCHECK(opener);
3951
3952   content::WebContents* web_contents =
3953       content::WebContents::FromRenderFrameHost(opener);
3954   Profile* profile =
3955       Profile::FromBrowserContext(web_contents->GetBrowserContext());
3956   DCHECK(profile);
3957   *no_javascript_access = false;
3958
3959 #if BUILDFLAG(IS_CHROMEOS_ASH)
3960   // Try to intercept the request and open the URL with Lacros.
3961   if (ash::TryOpenUrl(target_url, disposition)) {
3962     return false;
3963   }
3964 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
3965
3966   // If the opener is trying to create a background window but doesn't have
3967   // the appropriate permission, fail the attempt.
3968   if (container_type == content::mojom::WindowContainerType::BACKGROUND) {
3969 #if BUILDFLAG(ENABLE_EXTENSIONS)
3970     auto* process_map = extensions::ProcessMap::Get(profile);
3971     auto* registry = extensions::ExtensionRegistry::Get(profile);
3972     if (!URLHasExtensionPermission(process_map, registry, opener_url,
3973                                    opener->GetProcess()->GetID(),
3974                                    APIPermissionID::kBackground)) {
3975       return false;
3976     }
3977
3978     // Note: this use of GetExtensionOrAppByURL is safe but imperfect.  It may
3979     // return a recently installed Extension even if this CanCreateWindow call
3980     // was made by an old copy of the page in a normal web process.  That's ok,
3981     // because the permission check above would have caused an early return
3982     // already. We must use the full URL to find hosted apps, though, and not
3983     // just the origin.
3984     const Extension* extension =
3985         registry->enabled_extensions().GetExtensionOrAppByURL(opener_url);
3986     if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension))
3987       *no_javascript_access = true;
3988 #endif
3989
3990     return true;
3991   }
3992
3993 #if BUILDFLAG(ENABLE_EXTENSIONS)
3994   if (extensions::WebViewRendererState::GetInstance()->IsGuest(
3995           opener->GetProcess()->GetID())) {
3996     return true;
3997   }
3998
3999   if (target_url.SchemeIs(extensions::kExtensionScheme)) {
4000     // Intentionally duplicating |registry| code from above because we want to
4001     // reduce calls to retrieve them as this function is a SYNC IPC handler.
4002     auto* registry = extensions::ExtensionRegistry::Get(profile);
4003     const Extension* extension =
4004         registry->enabled_extensions().GetExtensionOrAppByURL(target_url);
4005     if (extension && extension->is_platform_app()) {
4006       UMA_HISTOGRAM_ENUMERATION(
4007           "Extensions.AppLoadedInTab",
4008           ClassifyAppLoadedInTabSource(opener_url, extension),
4009           APP_LOADED_IN_TAB_SOURCE_MAX);
4010
4011       // window.open() may not be used to load v2 apps in a regular tab.
4012       return false;
4013     }
4014   }
4015 #endif
4016
4017   DCHECK(!prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
4018       web_contents));
4019
4020   BlockedWindowParams blocked_params(
4021       target_url, source_origin, opener->GetSiteInstance(), referrer,
4022       frame_name, disposition, features, user_gesture, opener_suppressed);
4023   NavigateParams nav_params =
4024       blocked_params.CreateNavigateParams(opener->GetProcess(), web_contents);
4025   return !blocked_content::ConsiderForPopupBlocking(disposition) ||
4026          blocked_content::MaybeBlockPopup(
4027              web_contents, &opener_top_level_frame_url,
4028              (*g_popup_navigation_delegate_factory)(std::move(nav_params)),
4029              nullptr /*=open_url_params*/, blocked_params.features(),
4030              HostContentSettingsMapFactory::GetForProfile(profile)) != nullptr;
4031 }
4032
4033 content::SpeechRecognitionManagerDelegate*
4034 ChromeContentBrowserClient::CreateSpeechRecognitionManagerDelegate() {
4035   return new speech::ChromeSpeechRecognitionManagerDelegate();
4036 }
4037
4038 #if BUILDFLAG(IS_CHROMEOS_ASH)
4039 content::TtsControllerDelegate*
4040 ChromeContentBrowserClient::GetTtsControllerDelegate() {
4041   return TtsControllerDelegateImpl::GetInstance();
4042 }
4043 #endif
4044
4045 void ChromeContentBrowserClient::MaybeOverrideManifest(
4046     content::RenderFrameHost* render_frame_host,
4047     blink::mojom::ManifestPtr& manifest) {
4048 #if !BUILDFLAG(IS_ANDROID)
4049   Profile* profile =
4050       Profile::FromBrowserContext(render_frame_host->GetBrowserContext());
4051   auto* provider = web_app::WebAppProvider::GetForWebApps(profile);
4052   if (provider)
4053     provider->policy_manager().MaybeOverrideManifest(render_frame_host,
4054                                                      manifest);
4055 #endif
4056 }
4057
4058 content::TtsPlatform* ChromeContentBrowserClient::GetTtsPlatform() {
4059 #if !BUILDFLAG(IS_ANDROID)
4060   content::TtsController::GetInstance()->SetTtsEngineDelegate(
4061       TtsExtensionEngine::GetInstance());
4062 #endif
4063 #if BUILDFLAG(IS_CHROMEOS_ASH)
4064   return TtsPlatformImplChromeOs::GetInstance();
4065 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
4066   return TtsPlatformImplLacros::GetInstance();
4067 #else
4068   return nullptr;
4069 #endif
4070 }
4071
4072 void ChromeContentBrowserClient::OverrideWebkitPrefs(
4073     WebContents* web_contents,
4074     WebPreferences* web_prefs) {
4075   Profile* profile =
4076       Profile::FromBrowserContext(web_contents->GetBrowserContext());
4077   PrefService* prefs = profile->GetPrefs();
4078
4079 // Fill font preferences. These are not registered on Android
4080 // - http://crbug.com/308033, http://crbug.com/696364.
4081 #if !BUILDFLAG(IS_ANDROID)
4082   // Enabling the FontFamilyCache needs some KeyedService that might not be
4083   // available for some irregular profiles, like the System Profile.
4084   if (!AreKeyedServicesDisabledForProfileByDefault(profile)) {
4085     FontFamilyCache::FillFontFamilyMap(profile,
4086                                        prefs::kWebKitStandardFontFamilyMap,
4087                                        &web_prefs->standard_font_family_map);
4088     FontFamilyCache::FillFontFamilyMap(profile,
4089                                        prefs::kWebKitFixedFontFamilyMap,
4090                                        &web_prefs->fixed_font_family_map);
4091     FontFamilyCache::FillFontFamilyMap(profile,
4092                                        prefs::kWebKitSerifFontFamilyMap,
4093                                        &web_prefs->serif_font_family_map);
4094     FontFamilyCache::FillFontFamilyMap(profile,
4095                                        prefs::kWebKitSansSerifFontFamilyMap,
4096                                        &web_prefs->sans_serif_font_family_map);
4097     FontFamilyCache::FillFontFamilyMap(profile,
4098                                        prefs::kWebKitCursiveFontFamilyMap,
4099                                        &web_prefs->cursive_font_family_map);
4100     FontFamilyCache::FillFontFamilyMap(profile,
4101                                        prefs::kWebKitFantasyFontFamilyMap,
4102                                        &web_prefs->fantasy_font_family_map);
4103     FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitMathFontFamilyMap,
4104                                        &web_prefs->math_font_family_map);
4105   }
4106
4107   web_prefs->default_font_size =
4108       prefs->GetInteger(prefs::kWebKitDefaultFontSize);
4109   web_prefs->default_fixed_font_size =
4110       prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
4111   web_prefs->minimum_font_size =
4112       prefs->GetInteger(prefs::kWebKitMinimumFontSize);
4113   web_prefs->minimum_logical_font_size =
4114       prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);
4115 #endif
4116
4117   web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
4118
4119   web_prefs->dom_paste_enabled =
4120       prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
4121   web_prefs->javascript_can_access_clipboard =
4122       prefs->GetBoolean(prefs::kWebKitJavascriptCanAccessClipboard);
4123   web_prefs->tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);
4124
4125   if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled))
4126     web_prefs->javascript_enabled = false;
4127
4128   if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled))
4129     web_prefs->web_security_enabled = false;
4130
4131   if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled))
4132     web_prefs->plugins_enabled = false;
4133   web_prefs->loads_images_automatically =
4134       prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
4135
4136   if (prefs->GetBoolean(prefs::kDisable3DAPIs)) {
4137     web_prefs->webgl1_enabled = false;
4138     web_prefs->webgl2_enabled = false;
4139   }
4140
4141   web_prefs->allow_running_insecure_content =
4142       prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent);
4143 #if BUILDFLAG(IS_ANDROID)
4144   web_prefs->font_scale_factor = static_cast<float>(
4145       prefs->GetDouble(browser_ui::prefs::kWebKitFontScaleFactor));
4146   web_prefs->text_size_contrast_factor =
4147       prefs->GetInteger(prefs::kAccessibilityTextSizeContrastFactor);
4148   web_prefs->force_enable_zoom =
4149       prefs->GetBoolean(browser_ui::prefs::kWebKitForceEnableZoom);
4150   web_prefs->font_weight_adjustment =
4151       prefs->GetInteger(prefs::kAccessibilityFontWeightAdjustment);
4152 #endif
4153   web_prefs->force_dark_mode_enabled =
4154       prefs->GetBoolean(prefs::kWebKitForceDarkModeEnabled);
4155
4156 #if BUILDFLAG(IS_CHROMEOS_ASH)
4157   web_prefs->always_show_focus =
4158       prefs->GetBoolean(ash::prefs::kAccessibilityFocusHighlightEnabled);
4159 #else
4160   if (features::IsAccessibilityFocusHighlightEnabled()) {
4161     web_prefs->always_show_focus =
4162         prefs->GetBoolean(prefs::kAccessibilityFocusHighlightEnabled);
4163   }
4164 #endif
4165
4166 #if BUILDFLAG(IS_ANDROID)
4167   web_prefs->password_echo_enabled =
4168       prefs->GetBoolean(prefs::kWebKitPasswordEchoEnabled);
4169 #else
4170   web_prefs->password_echo_enabled = false;
4171 #endif
4172
4173   web_prefs->text_areas_are_resizable =
4174       prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);
4175   web_prefs->hyperlink_auditing_enabled =
4176       prefs->GetBoolean(prefs::kEnableHyperlinkAuditing);
4177
4178 #if BUILDFLAG(ENABLE_EXTENSIONS)
4179   std::string image_animation_policy =
4180       prefs->GetString(prefs::kAnimationPolicy);
4181   if (image_animation_policy == kAnimationPolicyOnce) {
4182     web_prefs->animation_policy =
4183         blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAnimateOnce;
4184   } else if (image_animation_policy == kAnimationPolicyNone) {
4185     web_prefs->animation_policy =
4186         blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation;
4187   } else {
4188     web_prefs->animation_policy =
4189         blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
4190   }
4191 #endif
4192
4193   // Make sure we will set the default_encoding with canonical encoding name.
4194   web_prefs->default_encoding =
4195       base::GetCanonicalEncodingNameByAliasName(web_prefs->default_encoding);
4196   if (web_prefs->default_encoding.empty()) {
4197     prefs->ClearPref(prefs::kDefaultCharset);
4198     web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
4199   }
4200   DCHECK(!web_prefs->default_encoding.empty());
4201
4202   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
4203           switches::kEnablePotentiallyAnnoyingSecurityFeatures)) {
4204     web_prefs->disable_reading_from_canvas = true;
4205     web_prefs->strict_mixed_content_checking = true;
4206     web_prefs->strict_powerful_feature_restrictions = true;
4207   }
4208
4209   // See crbug.com/1238157: the Native Client flag (chrome://flags/#enable-nacl)
4210   // can be manually re-enabled. In that case, we also need to return the full
4211   // plugins list, for compat.
4212   web_prefs->allow_non_empty_navigator_plugins |=
4213       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl);
4214
4215   web_prefs->data_saver_enabled = IsDataSaverEnabled(profile);
4216
4217   if (web_contents) {
4218 #if BUILDFLAG(IS_ANDROID)
4219     auto* delegate = TabAndroid::FromWebContents(web_contents)
4220                          ? static_cast<android::TabWebContentsDelegateAndroid*>(
4221                                web_contents->GetDelegate())
4222                          : nullptr;
4223     if (delegate) {
4224       web_prefs->embedded_media_experience_enabled =
4225           delegate->ShouldEnableEmbeddedMediaExperience();
4226
4227       web_prefs->picture_in_picture_enabled =
4228           delegate->IsPictureInPictureEnabled();
4229
4230       web_prefs->force_dark_mode_enabled =
4231           delegate->IsForceDarkWebContentEnabled();
4232
4233       web_prefs->modal_context_menu = delegate->IsModalContextMenu();
4234     }
4235 #endif  // BUILDFLAG(IS_ANDROID)
4236
4237     // web_app_scope value is platform specific.
4238 #if BUILDFLAG(IS_ANDROID)
4239     if (delegate)
4240       web_prefs->web_app_scope = delegate->GetManifestScope();
4241 #elif BUILDFLAG(ENABLE_EXTENSIONS)
4242     {
4243       web_prefs->web_app_scope = GURL();
4244       // Set |web_app_scope| based on the app associated with the app window if
4245       // any. Note that the app associated with the window never changes, even
4246       // if the app navigates off scope. This is not a problem because we still
4247       // want to use the scope of the app associated with the window, not the
4248       // WebContents.
4249       Browser* browser = chrome::FindBrowserWithTab(web_contents);
4250       if (browser && browser->app_controller()) {
4251         web_app::WebAppProvider* const web_app_provider =
4252             web_app::WebAppProvider::GetForLocalAppsUnchecked(profile);
4253         const webapps::AppId& app_id = browser->app_controller()->app_id();
4254         const web_app::WebAppRegistrar& registrar =
4255             web_app_provider->registrar_unsafe();
4256         if (registrar.IsLocallyInstalled(app_id))
4257           web_prefs->web_app_scope = registrar.GetAppScope(app_id);
4258
4259 #if BUILDFLAG(IS_CHROMEOS_ASH)
4260         auto* system_app = browser->app_controller()->system_app();
4261         if (system_app) {
4262           web_prefs->allow_scripts_to_close_windows =
4263               system_app->ShouldAllowScriptsToCloseWindows();
4264         }
4265 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
4266       }
4267     }
4268 #endif
4269
4270     web_prefs->immersive_mode_enabled = vr::VrTabHelper::IsInVr(web_contents);
4271   }
4272
4273   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
4274           switches::kDisableLazyLoading)) {
4275     web_prefs->lazy_load_enabled = false;
4276   } else {
4277     web_prefs->lazy_load_enabled =
4278         !web_contents || !web_contents->GetDelegate() ||
4279         web_contents->GetDelegate()->ShouldAllowLazyLoad();
4280   }
4281
4282   if (base::FeatureList::IsEnabled(
4283           features::kNetworkQualityEstimatorWebHoldback)) {
4284     std::string effective_connection_type_param =
4285         base::GetFieldTrialParamValueByFeature(
4286             features::kNetworkQualityEstimatorWebHoldback,
4287             "web_effective_connection_type_override");
4288
4289     absl::optional<net::EffectiveConnectionType> effective_connection_type =
4290         net::GetEffectiveConnectionTypeForName(effective_connection_type_param);
4291     DCHECK(effective_connection_type_param.empty() ||
4292            effective_connection_type);
4293     if (effective_connection_type) {
4294       DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
4295                 effective_connection_type.value());
4296       web_prefs->network_quality_estimator_web_holdback =
4297           static_cast<EffectiveConnectionType>(
4298               effective_connection_type.value());
4299     }
4300   }
4301
4302   web_prefs->autoplay_policy = GetAutoplayPolicyForWebContents(web_contents);
4303 #if !BUILDFLAG(IS_ANDROID)
4304   web_prefs->require_transient_activation_for_get_display_media =
4305       capture_policy::IsTransientActivationRequiredForGetDisplayMedia(
4306           web_contents);
4307   web_prefs->require_transient_activation_for_show_file_or_directory_picker =
4308       IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents);
4309 #endif  // !BUILDFLAG(IS_ANDROID)
4310
4311   switch (GetWebTheme()->GetPreferredContrast()) {
4312     case ui::NativeTheme::PreferredContrast::kNoPreference:
4313       web_prefs->preferred_contrast =
4314           blink::mojom::PreferredContrast::kNoPreference;
4315       break;
4316     case ui::NativeTheme::PreferredContrast::kMore:
4317       web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kMore;
4318       break;
4319     case ui::NativeTheme::PreferredContrast::kLess:
4320       web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kLess;
4321       break;
4322     case ui::NativeTheme::PreferredContrast::kCustom:
4323       web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kCustom;
4324       break;
4325   }
4326
4327   UpdatePreferredColorScheme(
4328       web_prefs,
4329       web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
4330       web_contents, GetWebTheme());
4331
4332   web_prefs->translate_service_available = TranslateService::IsAvailable(prefs);
4333
4334   absl::optional<ui::CaptionStyle> style =
4335       captions::GetCaptionStyleFromUserSettings(prefs,
4336                                                 true /* record_metrics */);
4337   if (style) {
4338     web_prefs->text_track_background_color = style->background_color;
4339     web_prefs->text_track_text_color = style->text_color;
4340     web_prefs->text_track_text_size = style->text_size;
4341     web_prefs->text_track_text_shadow = style->text_shadow;
4342     web_prefs->text_track_font_family = style->font_family;
4343     web_prefs->text_track_font_variant = style->font_variant;
4344     web_prefs->text_track_window_color = style->window_color;
4345     web_prefs->text_track_window_radius = style->window_radius;
4346   }
4347
4348 #if BUILDFLAG(IS_ANDROID)
4349   // If the pref is not set, the default value (true) will be used:
4350   web_prefs->webxr_immersive_ar_allowed =
4351       prefs->GetBoolean(prefs::kWebXRImmersiveArEnabled);
4352 #endif
4353
4354   // Only set `databases_enabled` if disabled. Otherwise check blink::feature
4355   // settings for Origin Trial and Chrome flag settings, or prefs setting
4356   // for Enterprise Policy.
4357   web_prefs->databases_enabled =
4358       !web_prefs->databases_enabled
4359           ? false
4360           : (base::FeatureList::IsEnabled(blink::features::kWebSQLAccess) ||
4361              prefs->GetBoolean(storage::kWebSQLAccess));
4362
4363 #if BUILDFLAG(IS_FUCHSIA)
4364   // Disable WebSQL support since it is being removed from the web platform
4365   // and does not work. See crbug.com/1317431.
4366   web_prefs->databases_enabled = false;
4367
4368   // TODO(crbug.com/1311019): Implement WebAuthn integration and remove.
4369   web_prefs->disable_webauthn = true;
4370 #endif
4371
4372   for (auto& parts : extra_parts_) {
4373     parts->OverrideWebkitPrefs(web_contents, web_prefs);
4374   }
4375 }
4376
4377 bool ChromeContentBrowserClientParts::OverrideWebPreferencesAfterNavigation(
4378     WebContents* web_contents,
4379     WebPreferences* web_prefs) {
4380   return false;
4381 }
4382
4383 bool ChromeContentBrowserClient::OverrideWebPreferencesAfterNavigation(
4384     WebContents* web_contents,
4385     WebPreferences* web_prefs) {
4386   bool prefs_changed = false;
4387
4388   const auto autoplay_policy = GetAutoplayPolicyForWebContents(web_contents);
4389   prefs_changed |= (web_prefs->autoplay_policy != autoplay_policy);
4390   web_prefs->autoplay_policy = autoplay_policy;
4391
4392 #if !BUILDFLAG(IS_ANDROID)
4393   const bool require_transient_activation_for_get_display_media =
4394       capture_policy::IsTransientActivationRequiredForGetDisplayMedia(
4395           web_contents);
4396   prefs_changed |=
4397       (web_prefs->require_transient_activation_for_get_display_media !=
4398        require_transient_activation_for_get_display_media);
4399   web_prefs->require_transient_activation_for_get_display_media =
4400       require_transient_activation_for_get_display_media;
4401
4402   const bool require_transient_activation_for_show_file_or_directory_picker =
4403       IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents);
4404   prefs_changed |=
4405       (web_prefs
4406            ->require_transient_activation_for_show_file_or_directory_picker !=
4407        require_transient_activation_for_show_file_or_directory_picker);
4408   web_prefs->require_transient_activation_for_show_file_or_directory_picker =
4409       require_transient_activation_for_show_file_or_directory_picker;
4410 #endif  // !BUILDFLAG(IS_ANDROID)
4411
4412   for (auto& parts : extra_parts_) {
4413     prefs_changed |=
4414         parts->OverrideWebPreferencesAfterNavigation(web_contents, web_prefs);
4415   }
4416
4417   prefs_changed |=
4418       UpdatePreferredColorScheme(web_prefs, web_contents->GetLastCommittedURL(),
4419                                  web_contents, GetWebTheme());
4420
4421 #if BUILDFLAG(IS_ANDROID)
4422   auto* delegate = TabAndroid::FromWebContents(web_contents)
4423                        ? static_cast<android::TabWebContentsDelegateAndroid*>(
4424                              web_contents->GetDelegate())
4425                        : nullptr;
4426   if (delegate) {
4427     bool force_dark_mode_new_state = delegate->IsForceDarkWebContentEnabled();
4428     prefs_changed |=
4429         (web_prefs->force_dark_mode_enabled != force_dark_mode_new_state);
4430     web_prefs->force_dark_mode_enabled = force_dark_mode_new_state;
4431   }
4432 #endif
4433
4434   return prefs_changed;
4435 }
4436
4437 void ChromeContentBrowserClient::BrowserURLHandlerCreated(
4438     BrowserURLHandler* handler) {
4439   // The group policy NTP URL handler must be registered before the other NTP
4440   // URL handlers below. Also register it before the "parts" handlers, so the
4441   // NTP policy takes precedence over extensions that override the NTP.
4442   handler->AddHandlerPair(&HandleNewTabPageLocationOverride,
4443                           BrowserURLHandler::null_handler());
4444
4445   for (auto& part : extra_parts_) {
4446     part->BrowserURLHandlerCreated(handler);
4447   }
4448
4449   // Handler to rewrite chrome://about and chrome://sync URLs.
4450   handler->AddHandlerPair(&HandleChromeAboutAndChromeSyncRewrite,
4451                           BrowserURLHandler::null_handler());
4452
4453 #if BUILDFLAG(IS_ANDROID)
4454   // Handler to rewrite chrome://newtab on Android.
4455   handler->AddHandlerPair(&chrome::android::HandleAndroidNativePageURL,
4456                           BrowserURLHandler::null_handler());
4457 #else   // BUILDFLAG(IS_ANDROID)
4458   // Handler to rewrite chrome://newtab for InstantExtended.
4459   handler->AddHandlerPair(&search::HandleNewTabURLRewrite,
4460                           &search::HandleNewTabURLReverseRewrite);
4461 #endif  // BUILDFLAG(IS_ANDROID)
4462
4463   // chrome: & friends.
4464   handler->AddHandlerPair(&ChromeContentBrowserClient::HandleWebUI,
4465                           &ChromeContentBrowserClient::HandleWebUIReverse);
4466 }
4467
4468 base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
4469   return DownloadPrefs::GetDefaultDownloadDirectory();
4470 }
4471
4472 std::string ChromeContentBrowserClient::GetDefaultDownloadName() {
4473   return l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME);
4474 }
4475
4476 base::FilePath ChromeContentBrowserClient::GetShaderDiskCacheDirectory() {
4477   base::FilePath user_data_dir;
4478   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
4479   DCHECK(!user_data_dir.empty());
4480   return user_data_dir.Append(FILE_PATH_LITERAL("ShaderCache"));
4481 }
4482
4483 base::FilePath ChromeContentBrowserClient::GetGrShaderDiskCacheDirectory() {
4484   base::FilePath user_data_dir;
4485   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
4486   DCHECK(!user_data_dir.empty());
4487   return user_data_dir.Append(FILE_PATH_LITERAL("GrShaderCache"));
4488 }
4489
4490 base::FilePath ChromeContentBrowserClient::GetGraphiteDawnDiskCacheDirectory() {
4491   base::FilePath user_data_dir;
4492   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
4493   return user_data_dir.Append(FILE_PATH_LITERAL("GraphiteDawnCache"));
4494 }
4495
4496 base::FilePath ChromeContentBrowserClient::GetNetLogDefaultDirectory() {
4497   base::FilePath user_data_dir;
4498   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
4499   DCHECK(!user_data_dir.empty());
4500   return user_data_dir;
4501 }
4502
4503 base::FilePath ChromeContentBrowserClient::GetFirstPartySetsDirectory() {
4504   base::FilePath user_data_dir;
4505   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
4506   DCHECK(!user_data_dir.empty());
4507   return user_data_dir;
4508 }
4509
4510 absl::optional<base::FilePath>
4511 ChromeContentBrowserClient::GetLocalTracesDirectory() {
4512   base::FilePath user_data_dir;
4513   if (!base::PathService::Get(chrome::DIR_LOCAL_TRACES, &user_data_dir)) {
4514     return absl::nullopt;
4515   }
4516   DCHECK(!user_data_dir.empty());
4517   return user_data_dir;
4518 }
4519
4520 void ChromeContentBrowserClient::DidCreatePpapiPlugin(
4521     content::BrowserPpapiHost* browser_host) {
4522 #if BUILDFLAG(ENABLE_PLUGINS)
4523   ChromeContentBrowserClientPluginsPart::DidCreatePpapiPlugin(browser_host);
4524 #endif
4525 }
4526
4527 content::BrowserPpapiHost*
4528 ChromeContentBrowserClient::GetExternalBrowserPpapiHost(int plugin_process_id) {
4529 #if BUILDFLAG(ENABLE_NACL)
4530   content::BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER);
4531   while (!iter.Done()) {
4532     nacl::NaClProcessHost* host =
4533         static_cast<nacl::NaClProcessHost*>(iter.GetDelegate());
4534     if (host->process() && host->process()->GetData().id == plugin_process_id) {
4535       // Found the plugin.
4536       return host->browser_ppapi_host();
4537     }
4538     ++iter;
4539   }
4540 #endif
4541   return nullptr;
4542 }
4543
4544 bool ChromeContentBrowserClient::AllowPepperSocketAPI(
4545     content::BrowserContext* browser_context,
4546     const GURL& url,
4547     bool private_api,
4548     const content::SocketPermissionRequest* params) {
4549 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
4550   return ChromeContentBrowserClientPluginsPart::AllowPepperSocketAPI(
4551       browser_context, url, private_api, params);
4552 #else
4553   return false;
4554 #endif
4555 }
4556
4557 bool ChromeContentBrowserClient::IsPepperVpnProviderAPIAllowed(
4558     content::BrowserContext* browser_context,
4559     const GURL& url) {
4560 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
4561   return ChromeContentBrowserClientPluginsPart::IsPepperVpnProviderAPIAllowed(
4562       browser_context, url);
4563 #else
4564   return false;
4565 #endif
4566 }
4567
4568 std::unique_ptr<content::VpnServiceProxy>
4569 ChromeContentBrowserClient::GetVpnServiceProxy(
4570     content::BrowserContext* browser_context) {
4571 #if BUILDFLAG(ENABLE_EXTENSIONS)
4572   return ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy(
4573       browser_context);
4574 #else
4575   return nullptr;
4576 #endif
4577 }
4578
4579 std::unique_ptr<ui::SelectFilePolicy>
4580 ChromeContentBrowserClient::CreateSelectFilePolicy(WebContents* web_contents) {
4581   return std::make_unique<ChromeSelectFilePolicy>(web_contents);
4582 }
4583
4584 void ChromeContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
4585     std::vector<std::string>* additional_allowed_schemes) {
4586   ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
4587       additional_allowed_schemes);
4588   additional_allowed_schemes->push_back(content::kChromeDevToolsScheme);
4589   additional_allowed_schemes->push_back(content::kChromeUIScheme);
4590   additional_allowed_schemes->push_back(content::kChromeUIUntrustedScheme);
4591   for (auto& extra_part : extra_parts_) {
4592     extra_part->GetAdditionalAllowedSchemesForFileSystem(
4593         additional_allowed_schemes);
4594   }
4595 }
4596
4597 void ChromeContentBrowserClient::GetSchemesBypassingSecureContextCheckAllowlist(
4598     std::set<std::string>* schemes) {
4599   *schemes = secure_origin_allowlist::GetSchemesBypassingSecureContextCheck();
4600 }
4601
4602 void ChromeContentBrowserClient::GetURLRequestAutoMountHandlers(
4603     std::vector<storage::URLRequestAutoMountHandler>* handlers) {
4604   for (auto& part : extra_parts_) {
4605     part->GetURLRequestAutoMountHandlers(handlers);
4606   }
4607 }
4608
4609 void ChromeContentBrowserClient::GetAdditionalFileSystemBackends(
4610     content::BrowserContext* browser_context,
4611     const base::FilePath& storage_partition_path,
4612     std::vector<std::unique_ptr<storage::FileSystemBackend>>*
4613         additional_backends) {
4614 #if BUILDFLAG(IS_CHROMEOS_ASH)
4615   storage::ExternalMountPoints* external_mount_points =
4616       browser_context->GetMountPoints();
4617   DCHECK(external_mount_points);
4618   auto backend = std::make_unique<ash::FileSystemBackend>(
4619       Profile::FromBrowserContext(browser_context),
4620       std::make_unique<ash::file_system_provider::BackendDelegate>(),
4621       std::make_unique<ash::MTPFileSystemBackendDelegate>(
4622           storage_partition_path),
4623       std::make_unique<arc::ArcContentFileSystemBackendDelegate>(),
4624       std::make_unique<arc::ArcDocumentsProviderBackendDelegate>(),
4625       std::make_unique<drive::DriveFsFileSystemBackendDelegate>(
4626           Profile::FromBrowserContext(browser_context)),
4627       std::make_unique<ash::smb_client::SmbFsFileSystemBackendDelegate>(
4628           Profile::FromBrowserContext(browser_context)),
4629       external_mount_points, storage::ExternalMountPoints::GetSystemInstance());
4630   backend->AddSystemMountPoints();
4631   DCHECK(backend->CanHandleType(storage::kFileSystemTypeExternal));
4632   additional_backends->push_back(std::move(backend));
4633 #endif
4634
4635   for (auto& part : extra_parts_) {
4636     part->GetAdditionalFileSystemBackends(
4637         browser_context, storage_partition_path,
4638         GetQuarantineConnectionCallback(), additional_backends);
4639   }
4640 }
4641
4642 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
4643 void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
4644     const base::CommandLine& command_line,
4645     int child_process_id,
4646     PosixFileDescriptorInfo* mappings) {
4647 #if BUILDFLAG(IS_ANDROID)
4648   base::MemoryMappedFile::Region region;
4649   int fd = ui::GetMainAndroidPackFd(&region);
4650   mappings->ShareWithRegion(kAndroidUIResourcesPakDescriptor, fd, region);
4651
4652   // For Android: Native resources for DFMs should only be used by the browser
4653   // process. Their file descriptors and memory mapped file regions are not
4654   // passed to child processes.
4655
4656   fd = ui::GetCommonResourcesPackFd(&region);
4657   mappings->ShareWithRegion(kAndroidChrome100PercentPakDescriptor, fd, region);
4658
4659   fd = ui::GetLocalePackFd(&region);
4660   mappings->ShareWithRegion(kAndroidLocalePakDescriptor, fd, region);
4661
4662   // Optional secondary locale .pak file.
4663   fd = ui::GetSecondaryLocalePackFd(&region);
4664   if (fd != -1) {
4665     mappings->ShareWithRegion(kAndroidSecondaryLocalePakDescriptor, fd, region);
4666   }
4667
4668   base::FilePath app_data_path;
4669   base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path);
4670   DCHECK(!app_data_path.empty());
4671 #endif  // BUILDFLAG(IS_ANDROID)
4672
4673 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
4674   int crash_signal_fd = GetCrashSignalFD(command_line);
4675   if (crash_signal_fd >= 0) {
4676     mappings->Share(kCrashDumpSignal, crash_signal_fd);
4677   }
4678 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
4679         // BUILDFLAG(IS_CHROMEOS)
4680
4681 #if BUILDFLAG(IS_CHROMEOS_LACROS)
4682   // Map startup and post-login parameter files to child processes in Lacros.
4683   // The FD numbers are passed via command line switches in
4684   // |AppendExtraCommandLineSwitches|.
4685   //
4686   // NOTE: the Zygote process requires special handling.
4687   // It doesn't need the post-login parameters, so it can be fully launched at
4688   // login screen. Also, serializing startup data early in the initialization
4689   // process requires temporarily initializing Mojo. That's handled in the
4690   // |LaunchZygoteHelper| function in |content_main_runner_impl.cc|. Here, we
4691   // deal with all other type of processes.
4692   std::string process_type =
4693       command_line.GetSwitchValueASCII(switches::kProcessType);
4694   if (process_type != switches::kZygoteProcess) {
4695     base::ScopedFD cros_startup_fd =
4696         chromeos::BrowserInitParams::CreateStartupData();
4697     if (cros_startup_fd.is_valid()) {
4698       constexpr int kStartupDataFD =
4699           kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor;
4700       mappings->Transfer(kStartupDataFD, std::move(cros_startup_fd));
4701     }
4702
4703     if (chromeos::IsLaunchedWithPostLoginParams()) {
4704       base::ScopedFD cros_postlogin_fd =
4705           chromeos::BrowserPostLoginParams::CreatePostLoginData();
4706       if (cros_postlogin_fd.is_valid()) {
4707         constexpr int kPostLoginDataFD =
4708             kCrosPostLoginDataDescriptor +
4709             base::GlobalDescriptors::kBaseDescriptor;
4710         mappings->Transfer(kPostLoginDataFD, std::move(cros_postlogin_fd));
4711       }
4712     }
4713   }
4714 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
4715 }
4716 #endif  // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
4717
4718 #if BUILDFLAG(IS_CHROMEOS_LACROS)
4719 void ChromeContentBrowserClient::GetAdditionalMappedFilesForZygote(
4720     base::CommandLine* command_line,
4721     PosixFileDescriptorInfo* mappings) {
4722   // Create the file descriptor for Cros startup data and pass it.
4723   // This FD will be used to obtain BrowserInitParams in Zygote process.
4724   // Note that this requires Mojo, but Mojo cannot be fully initialized this
4725   // due to dependencies on base::FeatureList. So we also temporarily initialize
4726   // Mojo and then shut it down immediately after preparing the FD. This is
4727   // inexpensive, an the features which control Mojo behavior aren't relevant
4728   // for this operation.
4729   //
4730   // TODO(https://crbug.com/1299283): This will need to be changed before
4731   // MojoIpcz experimentation can happen on Lacros, as it results in
4732   // inconsistent MojoIpcz feature status across Mojo initializations.
4733   mojo::core::Init();
4734   base::ScopedFD cros_startup_fd =
4735       chromeos::BrowserInitParams::CreateStartupData();
4736   mojo::core::ShutDown();
4737
4738   if (cros_startup_fd.is_valid()) {
4739     constexpr int kStartupDataFD =
4740         kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor;
4741     command_line->AppendSwitchASCII(chromeos::switches::kCrosStartupDataFD,
4742                                     base::NumberToString(kStartupDataFD));
4743     mappings->Transfer(kStartupDataFD, std::move(cros_startup_fd));
4744   }
4745 }
4746 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
4747
4748 #if BUILDFLAG(IS_WIN)
4749 std::wstring ChromeContentBrowserClient::GetAppContainerSidForSandboxType(
4750     sandbox::mojom::Sandbox sandbox_type,
4751     AppContainerFlags flags) {
4752   // TODO(wfh): Add support for more process types here. crbug.com/499523
4753   switch (sandbox_type) {
4754     case sandbox::mojom::Sandbox::kRenderer:
4755       if (flags & AppContainerFlags::kAppContainerFlagDisableAppContainer)
4756         return std::wstring();
4757       return std::wstring(install_static::GetSandboxSidPrefix()) + L"129201922";
4758     case sandbox::mojom::Sandbox::kUtility:
4759       return std::wstring();
4760     case sandbox::mojom::Sandbox::kGpu:
4761       return std::wstring();
4762     case sandbox::mojom::Sandbox::kOnDeviceModelExecution:
4763       return std::wstring();
4764 #if BUILDFLAG(ENABLE_PPAPI)
4765     case sandbox::mojom::Sandbox::kPpapi:
4766 #endif
4767     case sandbox::mojom::Sandbox::kNoSandbox:
4768     case sandbox::mojom::Sandbox::kNoSandboxAndElevatedPrivileges:
4769     case sandbox::mojom::Sandbox::kXrCompositing:
4770     case sandbox::mojom::Sandbox::kNetwork:
4771     case sandbox::mojom::Sandbox::kCdm:
4772 #if BUILDFLAG(ENABLE_OOP_PRINTING)
4773     case sandbox::mojom::Sandbox::kPrintBackend:
4774 #endif
4775     case sandbox::mojom::Sandbox::kPrintCompositor:
4776     case sandbox::mojom::Sandbox::kAudio:
4777 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
4778     case sandbox::mojom::Sandbox::kScreenAI:
4779 #endif
4780     case sandbox::mojom::Sandbox::kSpeechRecognition:
4781     case sandbox::mojom::Sandbox::kPdfConversion:
4782     case sandbox::mojom::Sandbox::kService:
4783     case sandbox::mojom::Sandbox::kServiceWithJit:
4784     case sandbox::mojom::Sandbox::kIconReader:
4785     case sandbox::mojom::Sandbox::kMediaFoundationCdm:
4786     case sandbox::mojom::Sandbox::kWindowsSystemProxyResolver:
4787       // Should never reach here.
4788       CHECK(0);
4789       return std::wstring();
4790   }
4791 }
4792
4793 bool ChromeContentBrowserClient::IsRendererAppContainerDisabled() {
4794   DCHECK_CURRENTLY_ON(BrowserThread::UI);
4795
4796   PrefService* local_state = g_browser_process->local_state();
4797   const PrefService::Preference* pref =
4798       local_state->FindPreference(prefs::kRendererAppContainerEnabled);
4799   // App Container is disabled if managed pref is set to false.
4800   if (pref && pref->IsManaged() && !pref->GetValue()->GetBool())
4801     return true;
4802
4803   return false;
4804 }
4805
4806 std::wstring
4807 ChromeContentBrowserClient::GetLPACCapabilityNameForNetworkService() {
4808   // Use a different LPAC capability name for each Chrome channel so network
4809   // service data between hannels is isolated.
4810   version_info::Channel channel = chrome::GetChannel();
4811   switch (channel) {
4812     case version_info::Channel::CANARY:
4813       return std::wstring(L"lpacChromeCanaryNetworkSandbox");
4814     case version_info::Channel::BETA:
4815       return std::wstring(L"lpacChromeBetaNetworkSandbox");
4816     case version_info::Channel::DEV:
4817       return std::wstring(L"lpacChromeDevNetworkSandbox");
4818     case version_info::Channel::STABLE:
4819       return std::wstring(L"lpacChromeStableNetworkSandbox");
4820     case version_info::Channel::UNKNOWN:
4821       return std::wstring(L"lpacChromeNetworkSandbox");
4822   }
4823 }
4824
4825 // Note: Only use sparingly to add Chrome specific sandbox functionality here.
4826 // Other code should reside in the content layer. Changes to this function
4827 // should be reviewed by the security team.
4828 bool ChromeContentBrowserClient::PreSpawnChild(
4829     sandbox::TargetConfig* config,
4830     sandbox::mojom::Sandbox sandbox_type,
4831     ChildSpawnFlags flags) {
4832   DCHECK(!config->IsConfigured());
4833 // Does not work under component build because all the component DLLs would need
4834 // to be manually added and maintained. Does not work under ASAN build because
4835 // ASAN has not yet fully initialized its instrumentation by the time the CIG
4836 // intercepts run.
4837 #if !defined(COMPONENT_BUILD) && !defined(ADDRESS_SANITIZER)
4838   bool enforce_code_integrity = false;
4839
4840   switch (sandbox_type) {
4841     case sandbox::mojom::Sandbox::kRenderer:
4842       enforce_code_integrity =
4843           (flags & ChildSpawnFlags::kChildSpawnFlagRendererCodeIntegrity);
4844       break;
4845     case sandbox::mojom::Sandbox::kNetwork:
4846       enforce_code_integrity =
4847           base::FeatureList::IsEnabled(kNetworkServiceCodeIntegrity);
4848       break;
4849     case sandbox::mojom::Sandbox::kServiceWithJit:
4850       enforce_code_integrity = true;
4851       break;
4852     case sandbox::mojom::Sandbox::kUtility:
4853     case sandbox::mojom::Sandbox::kGpu:
4854 #if BUILDFLAG(ENABLE_PPAPI)
4855     case sandbox::mojom::Sandbox::kPpapi:
4856 #endif
4857     case sandbox::mojom::Sandbox::kNoSandbox:
4858     case sandbox::mojom::Sandbox::kNoSandboxAndElevatedPrivileges:
4859     case sandbox::mojom::Sandbox::kXrCompositing:
4860     case sandbox::mojom::Sandbox::kCdm:
4861 #if BUILDFLAG(ENABLE_PRINTING)
4862     case sandbox::mojom::Sandbox::kPrintBackend:
4863 #endif
4864     case sandbox::mojom::Sandbox::kPrintCompositor:
4865 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
4866     case sandbox::mojom::Sandbox::kScreenAI:
4867 #endif
4868     case sandbox::mojom::Sandbox::kAudio:
4869     case sandbox::mojom::Sandbox::kOnDeviceModelExecution:
4870     case sandbox::mojom::Sandbox::kSpeechRecognition:
4871     case sandbox::mojom::Sandbox::kPdfConversion:
4872     case sandbox::mojom::Sandbox::kService:
4873     case sandbox::mojom::Sandbox::kIconReader:
4874     case sandbox::mojom::Sandbox::kMediaFoundationCdm:
4875     case sandbox::mojom::Sandbox::kWindowsSystemProxyResolver:
4876       break;
4877   }
4878
4879 #if !defined(OFFICIAL_BUILD)
4880   // Disable renderer code integrity when Application Verifier or pageheap are
4881   // enabled for chrome.exe to avoid renderer crashes. https://crbug.com/1004989
4882   if (base::win::IsAppVerifierEnabled(chrome::kBrowserProcessExecutableName))
4883     enforce_code_integrity = false;
4884 #endif  // !defined(OFFICIAL_BUILD)
4885
4886   if (!enforce_code_integrity)
4887     return true;
4888
4889   // Only enable signing mitigation if launching from chrome.exe.
4890   base::FilePath exe_path;
4891   if (!base::PathService::Get(base::FILE_EXE, &exe_path))
4892     return true;
4893   if (chrome::kBrowserProcessExecutableName != exe_path.BaseName().value())
4894     return true;
4895
4896   sandbox::MitigationFlags mitigations = config->GetProcessMitigations();
4897   mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS;
4898   sandbox::ResultCode result = config->SetProcessMitigations(mitigations);
4899   if (result != sandbox::SBOX_ALL_OK)
4900     return false;
4901
4902   // Allow loading Chrome's DLLs.
4903   for (const auto* dll : {chrome::kBrowserResourcesDll, chrome::kElfDll}) {
4904     result = config->AllowExtraDlls(GetModulePath(dll).value().c_str());
4905     if (result != sandbox::SBOX_ALL_OK)
4906       return false;
4907   }
4908 #endif  // !defined(COMPONENT_BUILD) && !defined(ADDRESS_SANITIZER)
4909   return true;
4910 }
4911
4912 bool ChromeContentBrowserClient::IsRendererCodeIntegrityEnabled() {
4913   // Emergency 'on switch' to re-enable the policy if force-disabling it causes
4914   // issues.
4915   if (base::FeatureList::IsEnabled(
4916           sandbox::policy::features::kWinSboxForceRendererCodeIntegrity)) {
4917     return true;
4918   }
4919
4920   PrefService* local_state = g_browser_process->local_state();
4921
4922   // If kWinSboxForceRendererCodeIntegrity is set to disabled, then code
4923   // integrity defaults to enabled, unless specifically overridden by a policy
4924   // controlled pref being set to false.
4925   return !local_state->HasPrefPath(prefs::kRendererCodeIntegrityEnabled) ||
4926          local_state->GetBoolean(prefs::kRendererCodeIntegrityEnabled);
4927 }
4928
4929 // Note: Only use sparingly to add Chrome specific sandbox functionality here.
4930 // Other code should reside in the content layer. Changes to this function
4931 // should be reviewed by the security team.
4932 bool ChromeContentBrowserClient::IsUtilityCetCompatible(
4933     const std::string& utility_sub_type) {
4934   if (utility_sub_type == chrome::mojom::UtilWin::Name_)
4935     return false;
4936   return true;
4937 }
4938
4939 void ChromeContentBrowserClient::SessionEnding(
4940     absl::optional<DWORD> control_type) {
4941   chrome::SessionEnding();
4942 }
4943
4944 bool ChromeContentBrowserClient::ShouldEnableAudioProcessHighPriority() {
4945   return IsAudioProcessHighPriorityEnabled();
4946 }
4947
4948 #endif  // BUILDFLAG(IS_WIN)
4949
4950 void ChromeContentBrowserClient::
4951     RegisterMojoBinderPoliciesForSameOriginPrerendering(
4952         content::MojoBinderPolicyMap& policy_map) {
4953   // Changes to `policy_map` should be made in
4954   // RegisterChromeMojoBinderPoliciesForSameOriginPrerendering() which requires
4955   // security review.
4956   RegisterChromeMojoBinderPoliciesForSameOriginPrerendering(policy_map);
4957 }
4958
4959 void ChromeContentBrowserClient::OpenURL(
4960     content::SiteInstance* site_instance,
4961     const content::OpenURLParams& params,
4962     base::OnceCallback<void(content::WebContents*)> callback) {
4963   DCHECK_CURRENTLY_ON(BrowserThread::UI);
4964
4965   content::BrowserContext* browser_context = site_instance->GetBrowserContext();
4966
4967 #if BUILDFLAG(IS_ANDROID)
4968   ServiceTabLauncher::GetInstance()->LaunchTab(browser_context, params,
4969                                                std::move(callback));
4970 #else
4971   NavigateParams nav_params(Profile::FromBrowserContext(browser_context),
4972                             params.url, params.transition);
4973   nav_params.FillNavigateParamsFromOpenURLParams(params);
4974
4975   Navigate(&nav_params);
4976   std::move(callback).Run(nav_params.navigated_or_inserted_contents);
4977 #endif
4978 }
4979
4980 content::ControllerPresentationServiceDelegate*
4981 ChromeContentBrowserClient::GetControllerPresentationServiceDelegate(
4982     content::WebContents* web_contents) {
4983   if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) {
4984     return media_router::PresentationServiceDelegateImpl::
4985         GetOrCreateForWebContents(web_contents);
4986   }
4987   return nullptr;
4988 }
4989
4990 content::ReceiverPresentationServiceDelegate*
4991 ChromeContentBrowserClient::GetReceiverPresentationServiceDelegate(
4992     content::WebContents* web_contents) {
4993   if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) {
4994     // ReceiverPresentationServiceDelegateImpl exists only for WebContents
4995     // created for offscreen presentations. The WebContents must belong to
4996     // an incognito profile.
4997     if (auto* impl = media_router::ReceiverPresentationServiceDelegateImpl::
4998             FromWebContents(web_contents)) {
4999       DCHECK(web_contents->GetBrowserContext()->IsOffTheRecord());
5000       return impl;
5001     }
5002   }
5003   return nullptr;
5004 }
5005
5006 void ChromeContentBrowserClient::AddPresentationObserver(
5007     content::PresentationObserver* observer,
5008     content::WebContents* web_contents) {
5009   if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) {
5010     media_router::WebContentsPresentationManager::Get(web_contents)
5011         ->AddObserver(observer);
5012   }
5013 }
5014
5015 void ChromeContentBrowserClient::RemovePresentationObserver(
5016     content::PresentationObserver* observer,
5017     content::WebContents* web_contents) {
5018   if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) {
5019     media_router::WebContentsPresentationManager::Get(web_contents)
5020         ->RemoveObserver(observer);
5021   }
5022 }
5023
5024 std::vector<std::unique_ptr<content::NavigationThrottle>>
5025 ChromeContentBrowserClient::CreateThrottlesForNavigation(
5026     content::NavigationHandle* handle) {
5027   std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
5028
5029   // MetricsNavigationThrottle requires that it runs before NavigationThrottles
5030   // that may delay or cancel navigations, so only NavigationThrottles that
5031   // don't delay or cancel navigations (e.g. throttles that are only observing
5032   // callbacks without affecting navigation behavior) should be added before
5033   // MetricsNavigationThrottle.
5034   if (handle->IsInMainFrame()) {
5035     throttles.push_back(
5036         page_load_metrics::MetricsNavigationThrottle::Create(handle));
5037   }
5038
5039 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
5040   MaybeAddThrottle(
5041       SupervisedUserNavigationThrottle::MaybeCreateThrottleFor(handle),
5042       &throttles);
5043 #endif
5044
5045 #if BUILDFLAG(IS_ANDROID)
5046   // TODO(davidben): This is insufficient to integrate with prerender properly.
5047   // https://crbug.com/370595
5048   prerender::NoStatePrefetchContents* no_state_prefetch_contents =
5049       prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents(
5050           handle->GetWebContents());
5051   if (!no_state_prefetch_contents) {
5052     MaybeAddThrottle(
5053         navigation_interception::InterceptNavigationDelegate::
5054             MaybeCreateThrottleFor(
5055                 handle, navigation_interception::SynchronyMode::kAsync),
5056         &throttles);
5057   }
5058   throttles.push_back(InterceptOMADownloadNavigationThrottle::Create(handle));
5059
5060 #if BUILDFLAG(DFMIFY_DEV_UI)
5061   // If the DevUI DFM is already installed, then this is a no-op, except for the
5062   // side effect of ensuring that the DevUI DFM is loaded.
5063   MaybeAddThrottle(dev_ui::DevUiLoaderThrottle::MaybeCreateThrottleFor(handle),
5064                    &throttles);
5065 #endif  // BUILDFLAG(DFMIFY_DEV_UI)
5066
5067 #elif BUILDFLAG(ENABLE_EXTENSIONS)
5068   // Redirect some navigations to apps that have registered matching URL
5069   // handlers ('url_handlers' in the manifest).
5070   MaybeAddThrottle(
5071       PlatformAppNavigationRedirector::MaybeCreateThrottleFor(handle),
5072       &throttles);
5073 #endif
5074
5075 #if BUILDFLAG(IS_CHROMEOS_ASH)
5076   // Check if we need to add merge session throttle. This throttle will postpone
5077   // loading of main frames.
5078   if (handle->IsInMainFrame()) {
5079     // Add interstitial page while merge session process (cookie reconstruction
5080     // from OAuth2 refresh token in ChromeOS login) is still in progress while
5081     // we are attempting to load a google property.
5082     if (ash::merge_session_throttling_utils::ShouldAttachNavigationThrottle() &&
5083         !ash::merge_session_throttling_utils::AreAllSessionMergedAlready() &&
5084         handle->GetURL().SchemeIsHTTPOrHTTPS()) {
5085       throttles.push_back(ash::MergeSessionNavigationThrottle::Create(handle));
5086     }
5087   }
5088 #endif
5089
5090 #if BUILDFLAG(IS_CHROMEOS)
5091   auto disabled_app_throttle =
5092       apps::ChromeOsDisabledAppsThrottle::MaybeCreate(handle);
5093   if (disabled_app_throttle) {
5094     throttles.push_back(std::move(disabled_app_throttle));
5095   }
5096 #endif  // BUILDFLAG(IS_CHROMEOS)
5097
5098 #if !BUILDFLAG(IS_ANDROID)
5099   std::unique_ptr<apps::LinkCapturingNavigationThrottle::Delegate>
5100       link_capturing_delegate;
5101
5102 #if BUILDFLAG(IS_CHROMEOS)
5103   link_capturing_delegate =
5104       std::make_unique<apps::ChromeOsLinkCapturingDelegate>();
5105 #else
5106   link_capturing_delegate =
5107       std::make_unique<web_app::WebAppLinkCapturingDelegate>();
5108 #endif
5109   std::unique_ptr<content::NavigationThrottle> url_to_apps_throttle =
5110       apps::LinkCapturingNavigationThrottle::MaybeCreate(
5111           handle, std::move(link_capturing_delegate));
5112   if (url_to_apps_throttle) {
5113     throttles.push_back(std::move(url_to_apps_throttle));
5114   }
5115 #endif  // !BUILDFLAG(IS_ANDROID)
5116
5117   Profile* profile = Profile::FromBrowserContext(
5118       handle->GetWebContents()->GetBrowserContext());
5119
5120 #if BUILDFLAG(ENABLE_EXTENSIONS)
5121   if (!ChromeContentBrowserClientExtensionsPart::
5122           AreExtensionsDisabledForProfile(profile)) {
5123     throttles.push_back(
5124         std::make_unique<extensions::ExtensionNavigationThrottle>(handle));
5125
5126     MaybeAddThrottle(extensions::ExtensionsBrowserClient::Get()
5127                          ->GetUserScriptListener()
5128                          ->CreateNavigationThrottle(handle),
5129                      &throttles);
5130   }
5131 #endif
5132
5133 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
5134   MaybeAddThrottle(
5135       SupervisedUserGoogleAuthNavigationThrottle::MaybeCreate(handle),
5136       &throttles);
5137 #endif
5138
5139   if (auto* throttle_manager =
5140           subresource_filter::ContentSubresourceFilterThrottleManager::
5141               FromNavigationHandle(*handle)) {
5142     throttle_manager->MaybeAppendNavigationThrottles(handle, &throttles);
5143   }
5144
5145   MaybeAddThrottle(
5146       LookalikeUrlNavigationThrottle::MaybeCreateNavigationThrottle(handle),
5147       &throttles);
5148
5149   MaybeAddThrottle(PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(handle),
5150                    &throttles);
5151 #if BUILDFLAG(ENABLE_PDF)
5152   MaybeAddThrottle(pdf::PdfNavigationThrottle::MaybeCreateThrottleFor(
5153                        handle, std::make_unique<ChromePdfStreamDelegate>()),
5154                    &throttles);
5155 #endif  // BUILDFLAG(ENABLE_PDF)
5156
5157   MaybeAddThrottle(TabUnderNavigationThrottle::MaybeCreate(handle), &throttles);
5158
5159   MaybeAddThrottle(
5160       WellKnownChangePasswordNavigationThrottle::MaybeCreateThrottleFor(handle),
5161       &throttles);
5162
5163   MaybeAddThrottle(
5164       PasswordManagerNavigationThrottle::MaybeCreateThrottleFor(handle),
5165       &throttles);
5166
5167   throttles.push_back(std::make_unique<PolicyBlocklistNavigationThrottle>(
5168       handle, handle->GetWebContents()->GetBrowserContext()));
5169
5170   // Before setting up SSL error detection, configure SSLErrorHandler to invoke
5171   // the relevant extension API whenever an SSL interstitial is shown.
5172   SSLErrorHandler::SetClientCallbackOnInterstitialsShown(
5173       base::BindRepeating(&MaybeTriggerSecurityInterstitialShownEvent));
5174   content::WebContents* web_contents = handle->GetWebContents();
5175   throttles.push_back(std::make_unique<SSLErrorNavigationThrottle>(
5176       handle,
5177       std::make_unique<CertificateReportingServiceCertReporter>(web_contents),
5178       base::BindOnce(&HandleSSLErrorWrapper), base::BindOnce(&IsInHostedApp),
5179       base::BindOnce(
5180           &ShouldIgnoreSslInterstitialBecauseNavigationDefaultedToHttps)));
5181
5182   throttles.push_back(std::make_unique<LoginNavigationThrottle>(handle));
5183
5184   if (base::FeatureList::IsEnabled(omnibox::kDefaultTypedNavigationsToHttps)) {
5185     MaybeAddThrottle(
5186         TypedNavigationUpgradeThrottle::MaybeCreateThrottleFor(handle),
5187         &throttles);
5188   }
5189
5190 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
5191   MaybeAddThrottle(
5192       WebAppSettingsNavigationThrottle::MaybeCreateThrottleFor(handle),
5193       &throttles);
5194   MaybeAddThrottle(profile_management::ProfileManagementNavigationThrottle::
5195                        MaybeCreateThrottleFor(handle),
5196                    &throttles);
5197 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
5198
5199 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \
5200     BUILDFLAG(IS_CHROMEOS_ASH)
5201   MaybeAddThrottle(enterprise_connectors::DeviceTrustNavigationThrottle::
5202                        MaybeCreateThrottleFor(handle),
5203                    &throttles);
5204 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) ||
5205         // BUILDFLAG(IS_CHROMEOS_ASH)
5206
5207 #if !BUILDFLAG(IS_ANDROID)
5208   MaybeAddThrottle(DevToolsWindow::MaybeCreateNavigationThrottle(handle),
5209                    &throttles);
5210
5211   MaybeAddThrottle(NewTabPageNavigationThrottle::MaybeCreateThrottleFor(handle),
5212                    &throttles);
5213
5214   MaybeAddThrottle(
5215       web_app::TabbedWebAppNavigationThrottle::MaybeCreateThrottleFor(handle),
5216       &throttles);
5217
5218   MaybeAddThrottle(
5219       web_app::WebUIWebAppNavigationThrottle::MaybeCreateThrottleFor(handle),
5220       &throttles);
5221 #endif
5222
5223   // g_browser_process->safe_browsing_service() may be null in unittests.
5224   safe_browsing::SafeBrowsingUIManager* ui_manager =
5225       g_browser_process->safe_browsing_service()
5226           ? g_browser_process->safe_browsing_service()->ui_manager().get()
5227           : nullptr;
5228   MaybeAddThrottle(
5229       safe_browsing::SafeBrowsingNavigationThrottle::MaybeCreateThrottleFor(
5230           handle, ui_manager),
5231       &throttles);
5232
5233   if (base::FeatureList::IsEnabled(safe_browsing::kDelayedWarnings)) {
5234     throttles.push_back(
5235         std::make_unique<safe_browsing::DelayedWarningNavigationThrottle>(
5236             handle));
5237   }
5238
5239 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
5240   MaybeAddThrottle(browser_switcher::BrowserSwitcherNavigationThrottle::
5241                        MaybeCreateThrottleFor(handle),
5242                    &throttles);
5243 #endif
5244
5245 #if BUILDFLAG(IS_CHROMEOS_ASH)
5246   MaybeAddThrottle(
5247       chromeos::KioskSettingsNavigationThrottle::MaybeCreateThrottleFor(handle),
5248       &throttles);
5249 #endif
5250
5251 #if BUILDFLAG(IS_MAC)
5252   MaybeAddThrottle(MaybeCreateAuthSessionThrottleFor(handle), &throttles);
5253 #endif
5254
5255   auto* performance_manager_registry =
5256       performance_manager::PerformanceManagerRegistry::GetInstance();
5257   if (performance_manager_registry) {
5258     MaybeAddThrottles(
5259         performance_manager_registry->CreateThrottlesForNavigation(handle),
5260         &throttles);
5261   }
5262
5263   if (profile && profile->GetPrefs()) {
5264     MaybeAddThrottle(
5265         security_interstitials::InsecureFormNavigationThrottle::
5266             MaybeCreateNavigationThrottle(
5267                 handle, std::make_unique<ChromeSecurityBlockingPageFactory>(),
5268                 profile->GetPrefs()),
5269         &throttles);
5270   }
5271
5272   if (IsErrorPageAutoReloadEnabled()) {
5273     MaybeAddThrottle(
5274         error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle),
5275         &throttles);
5276   }
5277
5278   MaybeAddThrottle(
5279       payments::PaymentHandlerNavigationThrottle::MaybeCreateThrottleFor(
5280           handle),
5281       &throttles);
5282
5283   MaybeAddThrottle(
5284       prerender::NoStatePrefetchNavigationThrottle::MaybeCreateThrottleFor(
5285           handle),
5286       &throttles);
5287
5288 #if defined(TOOLKIT_VIEWS)
5289   if (profile && IsSideSearchEnabled(profile)) {
5290     MaybeAddThrottle(
5291         SideSearchSideContentsHelper::MaybeCreateThrottleFor(handle),
5292         &throttles);
5293   }
5294 #endif
5295
5296 #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
5297   if (lens::features::IsLensSidePanelEnabled()) {
5298     MaybeAddThrottle(
5299         lens::LensSidePanelNavigationHelper::MaybeCreateThrottleFor(handle),
5300         &throttles);
5301   }
5302 #endif
5303
5304 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
5305   MaybeAddThrottle(
5306       offline_pages::OfflinePageNavigationThrottle::MaybeCreateThrottleFor(
5307           handle),
5308       &throttles);
5309 #endif
5310
5311   if (profile) {
5312     MaybeAddThrottle(
5313         HttpsUpgradesNavigationThrottle::MaybeCreateThrottleFor(
5314             handle, std::make_unique<ChromeSecurityBlockingPageFactory>(),
5315             profile),
5316         &throttles);
5317   }
5318
5319   MaybeAddThrottle(MaybeCreateNavigationAblationThrottle(handle), &throttles);
5320
5321 #if !BUILDFLAG(IS_ANDROID)
5322   MaybeAddThrottle(MaybeCreateAboutThisSiteThrottleFor(handle), &throttles);
5323 #endif
5324
5325   auto* privacy_sandbox_settings =
5326       PrivacySandboxSettingsFactory::GetForProfile(profile);
5327   if (privacy_sandbox_settings &&
5328       privacy_sandbox_settings->AreRelatedWebsiteSetsEnabled() &&
5329       base::FeatureList::IsEnabled(features::kFirstPartySets)) {
5330     MaybeAddThrottle(first_party_sets::FirstPartySetsNavigationThrottle::
5331                          MaybeCreateNavigationThrottle(handle),
5332                      &throttles);
5333   }
5334
5335 #if BUILDFLAG(IS_WIN)
5336   // Don't perform platform authentication in incognito and guest profiles.
5337   if (profile && !profile->IsOffTheRecord()) {
5338     MaybeAddThrottle(
5339         enterprise_auth::PlatformAuthNavigationThrottle::MaybeCreateThrottleFor(
5340             handle),
5341         &throttles);
5342   }
5343 #endif  // BUILDFLAG(IS_WIN)
5344
5345 #if BUILDFLAG(IS_CHROMEOS)
5346   // TODO(b:296844164) Handle captive portal signin properly.
5347   if (profile && profile->IsIncognitoProfile() && profile->IsOffTheRecord() &&
5348       !profile->GetOTRProfileID().IsCaptivePortal()) {
5349     MaybeAddThrottle(
5350         chromeos::IncognitoNavigationThrottle::MaybeCreateThrottleFor(handle),
5351         &throttles);
5352   }
5353 #endif  // BUILDFLAG(IS_CHROMEOS)
5354
5355 #if BUILDFLAG(IS_CHROMEOS_ASH)
5356   MaybeAddThrottle(apps::AppInstallNavigationThrottle::MaybeCreate(handle),
5357                    &throttles);
5358 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
5359
5360   return throttles;
5361 }
5362
5363 std::vector<std::unique_ptr<content::CommitDeferringCondition>>
5364 ChromeContentBrowserClient::CreateCommitDeferringConditionsForNavigation(
5365     content::NavigationHandle* navigation_handle,
5366     content::CommitDeferringCondition::NavigationType navigation_type) {
5367   auto conditions =
5368       std::vector<std::unique_ptr<content::CommitDeferringCondition>>();
5369
5370 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
5371   MaybeAddCondition(
5372       safe_browsing::MaybeCreateCommitDeferringCondition(*navigation_handle),
5373       &conditions);
5374 #endif
5375
5376   return conditions;
5377 }
5378
5379 std::unique_ptr<content::NavigationUIData>
5380 ChromeContentBrowserClient::GetNavigationUIData(
5381     content::NavigationHandle* navigation_handle) {
5382   return std::make_unique<ChromeNavigationUIData>(navigation_handle);
5383 }
5384
5385 std::unique_ptr<media::ScreenEnumerator>
5386 ChromeContentBrowserClient::CreateScreenEnumerator() const {
5387   return std::make_unique<ChromeScreenEnumerator>();
5388 }
5389
5390 bool ChromeContentBrowserClient::EnforceSystemAudioEchoCancellation() {
5391   // TODO(b/270042522): This is a short term solution to enforce the system
5392   // audio cancellation and will be removed before Lacros is released. The
5393   // short term solution will not work on Lacros.
5394 #if BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_CRAS)
5395   bool system_aec_enabled = false;
5396   ash::CrosSettings::Get()->GetBoolean(ash::kDeviceSystemAecEnabled,
5397                                        &system_aec_enabled);
5398   return system_aec_enabled;
5399 #else
5400   return false;
5401 #endif
5402 }
5403
5404 std::unique_ptr<content::DevToolsManagerDelegate>
5405 ChromeContentBrowserClient::CreateDevToolsManagerDelegate() {
5406 #if BUILDFLAG(IS_ANDROID)
5407   return std::make_unique<DevToolsManagerDelegateAndroid>();
5408 #else
5409   return std::make_unique<ChromeDevToolsManagerDelegate>();
5410 #endif
5411 }
5412
5413 void ChromeContentBrowserClient::UpdateDevToolsBackgroundServiceExpiration(
5414     content::BrowserContext* browser_context,
5415     int service,
5416     base::Time expiration_time) {
5417   Profile* profile = Profile::FromBrowserContext(browser_context);
5418   DCHECK(profile);
5419
5420   auto* pref_service = profile->GetPrefs();
5421   DCHECK(pref_service);
5422
5423   ScopedDictPrefUpdate pref_update(
5424       pref_service, prefs::kDevToolsBackgroundServicesExpirationDict);
5425   base::Value::Dict& exp_dict = pref_update.Get();
5426
5427   // Convert |expiration_time| to minutes since that is the most granular
5428   // option that returns an int. base::Value does not accept int64.
5429   int expiration_time_minutes =
5430       expiration_time.ToDeltaSinceWindowsEpoch().InMinutes();
5431   exp_dict.Set(base::NumberToString(service), expiration_time_minutes);
5432 }
5433
5434 base::flat_map<int, base::Time>
5435 ChromeContentBrowserClient::GetDevToolsBackgroundServiceExpirations(
5436     content::BrowserContext* browser_context) {
5437   Profile* profile = Profile::FromBrowserContext(browser_context);
5438   DCHECK(profile);
5439
5440   auto* pref_service = profile->GetPrefs();
5441   DCHECK(pref_service);
5442
5443   const auto& expiration_dict =
5444       pref_service->GetDict(prefs::kDevToolsBackgroundServicesExpirationDict);
5445
5446   base::flat_map<int, base::Time> expiration_times;
5447   for (auto it : expiration_dict) {
5448     // key.
5449     int service = 0;
5450     bool did_convert = base::StringToInt(it.first, &service);
5451     DCHECK(did_convert);
5452
5453     // value.
5454     DCHECK(it.second.is_int());
5455     base::TimeDelta delta = base::Minutes(it.second.GetInt());
5456     base::Time expiration_time = base::Time::FromDeltaSinceWindowsEpoch(delta);
5457
5458     expiration_times[service] = expiration_time;
5459   }
5460
5461   return expiration_times;
5462 }
5463
5464 content::TracingDelegate* ChromeContentBrowserClient::GetTracingDelegate() {
5465   return new ChromeTracingDelegate();
5466 }
5467
5468 bool ChromeContentBrowserClient::IsPluginAllowedToCallRequestOSFileHandle(
5469     content::BrowserContext* browser_context,
5470     const GURL& url) {
5471 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
5472   return ChromeContentBrowserClientPluginsPart::
5473       IsPluginAllowedToCallRequestOSFileHandle(browser_context, url);
5474 #else
5475   return false;
5476 #endif
5477 }
5478
5479 bool ChromeContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs(
5480     content::BrowserContext* browser_context,
5481     const GURL& url) {
5482 #if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS)
5483   return ChromeContentBrowserClientPluginsPart::
5484       IsPluginAllowedToUseDevChannelAPIs(browser_context, url);
5485 #else
5486   return false;
5487 #endif
5488 }
5489
5490 void ChromeContentBrowserClient::OverridePageVisibilityState(
5491     RenderFrameHost* render_frame_host,
5492     content::PageVisibilityState* visibility_state) {
5493   DCHECK_CURRENTLY_ON(BrowserThread::UI);
5494
5495   WebContents* web_contents =
5496       WebContents::FromRenderFrameHost(render_frame_host);
5497   DCHECK(web_contents);
5498
5499   prerender::NoStatePrefetchManager* no_state_prefetch_manager =
5500       prerender::NoStatePrefetchManagerFactory::GetForBrowserContext(
5501           web_contents->GetBrowserContext());
5502   if (no_state_prefetch_manager &&
5503       no_state_prefetch_manager->IsWebContentsPrefetching(web_contents)) {
5504     *visibility_state = content::PageVisibilityState::kHiddenButPainting;
5505   }
5506 }
5507
5508 void ChromeContentBrowserClient::InitOnUIThread() {
5509   DCHECK_CURRENTLY_ON(BrowserThread::UI);
5510
5511   safe_browsing_service_ = g_browser_process->safe_browsing_service();
5512
5513   // Initialize `network_contexts_parent_directory_`.
5514   base::FilePath user_data_dir;
5515   base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
5516   DCHECK(!user_data_dir.empty());
5517   network_contexts_parent_directory_.push_back(user_data_dir);
5518
5519   base::FilePath cache_dir;
5520   chrome::GetUserCacheDirectory(user_data_dir, &cache_dir);
5521   DCHECK(!cache_dir.empty());
5522   // On some platforms, the cache is a child of the user_data_dir so only
5523   // return the one path.
5524   if (!user_data_dir.IsParent(cache_dir))
5525     network_contexts_parent_directory_.push_back(cache_dir);
5526
5527   // If the cache location has been overridden by a switch or preference,
5528   // include that as well.
5529   if (auto* local_state = g_browser_process->local_state()) {
5530     base::FilePath pref_cache_dir =
5531         local_state->GetFilePath(prefs::kDiskCacheDir);
5532     if (!pref_cache_dir.empty() && !user_data_dir.IsParent(cache_dir))
5533       network_contexts_parent_directory_.push_back(pref_cache_dir);
5534   }
5535 }
5536
5537 void ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch(
5538     base::CommandLine* to_command_line,
5539     const base::CommandLine& from_command_line,
5540     version_info::Channel channel) {
5541 #if BUILDFLAG(IS_ANDROID)
5542   const version_info::Channel kMaxDisableEncryptionChannel =
5543       version_info::Channel::BETA;
5544 #else
5545   const version_info::Channel kMaxDisableEncryptionChannel =
5546       version_info::Channel::DEV;
5547 #endif
5548   if (channel <= kMaxDisableEncryptionChannel) {
5549     static const char* const kWebRtcDevSwitchNames[] = {
5550         switches::kDisableWebRtcEncryption,
5551     };
5552     to_command_line->CopySwitchesFrom(from_command_line, kWebRtcDevSwitchNames);
5553   }
5554 }
5555
5556 #if BUILDFLAG(ENABLE_MEDIA_REMOTING)
5557 void ChromeContentBrowserClient::CreateMediaRemoter(
5558     content::RenderFrameHost* render_frame_host,
5559     mojo::PendingRemote<media::mojom::RemotingSource> source,
5560     mojo::PendingReceiver<media::mojom::Remoter> receiver) {
5561   CastRemotingConnector::CreateMediaRemoter(
5562       render_frame_host, std::move(source), std::move(receiver));
5563 }
5564 #endif  // BUILDFLAG(ENABLE_MEDIA_REMOTING)
5565
5566 base::FilePath ChromeContentBrowserClient::GetLoggingFileName(
5567     const base::CommandLine& command_line) {
5568   return logging::GetLogFileName(command_line);
5569 }
5570
5571 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
5572 std::unique_ptr<blink::URLLoaderThrottle>
5573 ChromeContentBrowserClient::MaybeCreateSafeBrowsingURLLoaderThrottle(
5574     const network::ResourceRequest& request,
5575     content::BrowserContext* browser_context,
5576     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
5577     int frame_tree_node_id,
5578     Profile* profile) {
5579   bool matches_enterprise_allowlist = safe_browsing::IsURLAllowlistedByPolicy(
5580       request.url, *profile->GetPrefs());
5581   if (!matches_enterprise_allowlist) {
5582 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
5583     auto* connectors_service =
5584         enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext(
5585             browser_context);
5586     bool has_valid_dm_token =
5587         connectors_service &&
5588         connectors_service->GetDMTokenForRealTimeUrlCheck().has_value();
5589     bool is_enterprise_lookup_enabled =
5590         safe_browsing::RealTimePolicyEngine::CanPerformEnterpriseFullURLLookup(
5591             profile->GetPrefs(), has_valid_dm_token, profile->IsOffTheRecord());
5592 #else
5593     bool is_enterprise_lookup_enabled = false;
5594 #endif
5595     bool is_consumer_lookup_enabled =
5596         safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup(
5597             profile->GetPrefs(), profile->IsOffTheRecord(),
5598             g_browser_process->variations_service());
5599
5600     // |url_lookup_service| is used when real time url check is enabled.
5601     safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service =
5602         GetUrlLookupService(browser_context, is_enterprise_lookup_enabled,
5603                             is_consumer_lookup_enabled);
5604     safe_browsing::HashRealTimeService* hash_realtime_service =
5605         safe_browsing_service_
5606             ? safe_browsing_service_->GetHashRealTimeService(profile)
5607             : nullptr;
5608     safe_browsing::PingManager* ping_manager =
5609         safe_browsing_service_
5610             ? safe_browsing::ChromePingManagerFactory::GetForBrowserContext(
5611                   profile)
5612             : nullptr;
5613     safe_browsing::hash_realtime_utils::HashRealTimeSelection
5614         hash_realtime_selection =
5615             safe_browsing::hash_realtime_utils::DetermineHashRealTimeSelection(
5616                 profile->IsOffTheRecord(), profile->GetPrefs(),
5617                 safe_browsing::hash_realtime_utils::GetCountryCode(
5618                     g_browser_process->variations_service()),
5619                 /*log_usage_histograms=*/true);
5620
5621     return safe_browsing::BrowserURLLoaderThrottle::Create(
5622         base::BindOnce(
5623             &ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate,
5624             base::Unretained(this),
5625             safe_browsing::IsSafeBrowsingEnabled(*profile->GetPrefs()),
5626             // Should check for enterprise when safe browsing is disabled.
5627             /*should_check_on_sb_disabled=*/is_enterprise_lookup_enabled,
5628             safe_browsing::GetURLAllowlistByPolicy(profile->GetPrefs())),
5629         wc_getter, frame_tree_node_id,
5630         url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr,
5631         hash_realtime_service ? hash_realtime_service->GetWeakPtr() : nullptr,
5632         ping_manager ? ping_manager->GetWeakPtr() : nullptr,
5633         hash_realtime_selection);
5634   }
5635   return nullptr;
5636 }
5637 #endif
5638
5639 #if BUILDFLAG(IS_ANDROID)
5640 std::tuple<std::string /*client_data_header*/, bool /*is_custom_tab*/>
5641 GetClientDataHeader(int frame_tree_node_id) {
5642   std::string client_data_header;
5643   bool is_custom_tab = false;
5644   if (frame_tree_node_id != content::RenderFrameHost::kNoFrameTreeNodeId) {
5645     auto* web_contents = WebContents::FromFrameTreeNodeId(frame_tree_node_id);
5646     // Could be null if the FrameTreeNode's RenderFrameHost is shutting down.
5647     if (web_contents) {
5648       auto* client_data_header_observer =
5649           customtabs::ClientDataHeaderWebContentsObserver::FromWebContents(
5650               web_contents);
5651       if (client_data_header_observer) {
5652         client_data_header = client_data_header_observer->header();
5653       }
5654
5655       auto* delegate =
5656           TabAndroid::FromWebContents(web_contents)
5657               ? static_cast<android::TabWebContentsDelegateAndroid*>(
5658                     web_contents->GetDelegate())
5659               : nullptr;
5660       if (delegate) {
5661         is_custom_tab = delegate->IsCustomTab();
5662       }
5663     }
5664   }
5665   return {client_data_header, is_custom_tab};
5666 }
5667 #endif
5668
5669 std::unique_ptr<blink::URLLoaderThrottle> CreateGoogleURLLoaderThrottle(
5670 #if BUILDFLAG(IS_ANDROID)
5671     const std::string& client_data_header,
5672 #endif
5673     Profile* profile) {
5674 #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
5675   BoundSessionCookieRefreshService* bound_session_cookie_refresh_service =
5676       BoundSessionCookieRefreshServiceFactory::GetForProfile(profile);
5677   std::unique_ptr<BoundSessionRequestThrottledListener>
5678       bound_session_request_throttled_listener;
5679   chrome::mojom::BoundSessionThrottlerParamsPtr bound_session_throttler_params;
5680
5681   if (bound_session_cookie_refresh_service) {
5682     bound_session_request_throttled_listener =
5683         std::make_unique<BoundSessionRequestThrottledListenerBrowserImpl>(
5684             *bound_session_cookie_refresh_service);
5685     bound_session_throttler_params =
5686         bound_session_cookie_refresh_service->GetBoundSessionThrottlerParams();
5687   }
5688 #endif
5689
5690   chrome::mojom::DynamicParamsPtr dynamic_params =
5691       chrome::mojom::DynamicParams::New(
5692 #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
5693           std::move(bound_session_throttler_params),
5694 #endif
5695           profile->GetPrefs()->GetBoolean(
5696               policy::policy_prefs::kForceGoogleSafeSearch),
5697           profile->GetPrefs()->GetInteger(
5698               policy::policy_prefs::kForceYouTubeRestrict),
5699           profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps));
5700   return std::make_unique<GoogleURLLoaderThrottle>(
5701 #if BUILDFLAG(IS_ANDROID)
5702       client_data_header,
5703 #endif
5704 #if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS)
5705       std::move(bound_session_request_throttled_listener),
5706 #endif
5707       std::move(dynamic_params));
5708 }
5709
5710 std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
5711 ChromeContentBrowserClient::CreateURLLoaderThrottles(
5712     const network::ResourceRequest& request,
5713     content::BrowserContext* browser_context,
5714     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
5715     content::NavigationUIData* navigation_ui_data,
5716     int frame_tree_node_id) {
5717   DCHECK_CURRENTLY_ON(BrowserThread::UI);
5718
5719   std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
5720
5721   DCHECK(browser_context);
5722   Profile* profile = Profile::FromBrowserContext(browser_context);
5723   DCHECK(profile);
5724
5725   ChromeNavigationUIData* chrome_navigation_ui_data =
5726       static_cast<ChromeNavigationUIData*>(navigation_ui_data);
5727
5728 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
5729   if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle(
5730           request, browser_context, wc_getter, frame_tree_node_id, profile);
5731       safe_browsing_throttle) {
5732     result.push_back(std::move(safe_browsing_throttle));
5733   }
5734 #endif
5735
5736 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
5737   result.push_back(
5738       std::make_unique<captive_portal::CaptivePortalURLLoaderThrottle>(
5739           wc_getter.Run()));
5740 #endif
5741
5742   if (chrome_navigation_ui_data &&
5743       chrome_navigation_ui_data->is_no_state_prefetching()) {
5744     result.push_back(std::make_unique<prerender::PrerenderURLLoaderThrottle>(
5745         chrome_navigation_ui_data->prerender_histogram_prefix(),
5746         GetPrerenderCanceler(wc_getter)));
5747   }
5748
5749 #if BUILDFLAG(IS_ANDROID)
5750   auto [client_data_header, is_custom_tab] =
5751       GetClientDataHeader(frame_tree_node_id);
5752 #endif
5753
5754   if (auto google_throttle = CreateGoogleURLLoaderThrottle(
5755 #if BUILDFLAG(IS_ANDROID)
5756           client_data_header,
5757 #endif
5758           profile);
5759       google_throttle) {
5760     result.push_back(std::move(google_throttle));
5761   }
5762
5763   {
5764     auto* factory =
5765         ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context);
5766     // null in unit tests.
5767     if (factory) {
5768       result.push_back(
5769           std::make_unique<custom_handlers::ProtocolHandlerThrottle>(*factory));
5770     }
5771   }
5772
5773 #if BUILDFLAG(ENABLE_PLUGINS)
5774   result.push_back(std::make_unique<PluginResponseInterceptorURLLoaderThrottle>(
5775       request.destination, frame_tree_node_id));
5776 #endif
5777
5778 #if BUILDFLAG(IS_ANDROID)
5779   auto delegate = std::make_unique<signin::HeaderModificationDelegateImpl>(
5780       profile, /*incognito_enabled=*/!is_custom_tab);
5781 #else
5782   auto delegate =
5783       std::make_unique<signin::HeaderModificationDelegateImpl>(profile);
5784 #endif
5785
5786   auto signin_throttle =
5787       signin::URLLoaderThrottle::MaybeCreate(std::move(delegate), wc_getter);
5788   if (signin_throttle)
5789     result.push_back(std::move(signin_throttle));
5790
5791   return result;
5792 }
5793
5794 std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
5795 ChromeContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive(
5796     const network::ResourceRequest& request,
5797     content::BrowserContext* browser_context,
5798     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
5799     int frame_tree_node_id) {
5800   DCHECK_CURRENTLY_ON(BrowserThread::UI);
5801
5802   std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
5803
5804   DCHECK(browser_context);
5805   Profile* profile = Profile::FromBrowserContext(browser_context);
5806   DCHECK(profile);
5807
5808 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
5809   if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle(
5810           request, browser_context, wc_getter, frame_tree_node_id, profile);
5811       safe_browsing_throttle) {
5812     result.push_back(std::move(safe_browsing_throttle));
5813   }
5814 #endif
5815
5816 #if BUILDFLAG(IS_ANDROID)
5817   auto [client_data_header, unused_is_custom_tab] =
5818       GetClientDataHeader(frame_tree_node_id);
5819 #endif
5820
5821   if (auto google_throttle = CreateGoogleURLLoaderThrottle(
5822 #if BUILDFLAG(IS_ANDROID)
5823           client_data_header,
5824 #endif
5825           profile);
5826       google_throttle) {
5827     result.push_back(std::move(google_throttle));
5828   }
5829
5830   return result;
5831 }
5832
5833 void ChromeContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
5834     int frame_tree_node_id,
5835     ukm::SourceIdObj ukm_source_id,
5836     NonNetworkURLLoaderFactoryMap* factories) {
5837 #if BUILDFLAG(ENABLE_EXTENSIONS) || BUILDFLAG(IS_CHROMEOS_ASH) || \
5838     !BUILDFLAG(IS_ANDROID)
5839   content::WebContents* web_contents =
5840       content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
5841   content::BrowserContext* browser_context = web_contents->GetBrowserContext();
5842
5843 #if BUILDFLAG(ENABLE_EXTENSIONS)
5844   if (!ChromeContentBrowserClientExtensionsPart::
5845           AreExtensionsDisabledForProfile(browser_context)) {
5846     factories->emplace(
5847         extensions::kExtensionScheme,
5848         extensions::CreateExtensionNavigationURLLoaderFactory(
5849             browser_context, ukm_source_id,
5850             !!extensions::WebViewGuest::FromWebContents(web_contents)));
5851   }
5852 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
5853
5854   Profile* profile = Profile::FromBrowserContext(browser_context);
5855   // KeyedServices could be disabled based on the profile type, e.g. System
5856   // Profile doesn't construct services by default.
5857   if (AreKeyedServicesDisabledForProfileByDefault(profile))
5858     return;
5859
5860 #if BUILDFLAG(IS_CHROMEOS_ASH)
5861   factories->emplace(content::kExternalFileScheme,
5862                      ash::ExternalFileURLLoaderFactory::Create(
5863                          profile, content::ChildProcessHost::kInvalidUniqueID));
5864 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
5865 #if !BUILDFLAG(IS_ANDROID)
5866   if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
5867           browser_context) &&
5868       !browser_context->ShutdownStarted()) {
5869     // TODO(crbug.com/1365848): Only register the factory if we are already in
5870     // an isolated storage partition.
5871     factories->emplace(chrome::kIsolatedAppScheme,
5872                        web_app::IsolatedWebAppURLLoaderFactory::Create(
5873                            frame_tree_node_id, browser_context));
5874   }
5875 #endif  // !BUILDFLAG(IS_ANDROID)
5876 #endif  // BUILDFLAG(ENABLE_EXTENSIONS) || BUILDFLAG(IS_CHROMEOS_ASH) ||
5877         // !BUILDFLAG(IS_ANDROID)
5878 }
5879
5880 void ChromeContentBrowserClient::
5881     RegisterNonNetworkWorkerMainResourceURLLoaderFactories(
5882         content::BrowserContext* browser_context,
5883         NonNetworkURLLoaderFactoryMap* factories) {
5884   DCHECK(browser_context);
5885   DCHECK(factories);
5886
5887 #if !BUILDFLAG(IS_ANDROID)
5888   if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
5889           browser_context) &&
5890       !browser_context->ShutdownStarted()) {
5891     factories->emplace(
5892         chrome::kIsolatedAppScheme,
5893         web_app::IsolatedWebAppURLLoaderFactory::CreateForServiceWorker(
5894             browser_context));
5895   }
5896 #endif  // !BUILDFLAG(IS_ANDROID)
5897
5898 #if BUILDFLAG(ENABLE_EXTENSIONS)
5899   DCHECK(!ChromeContentBrowserClientExtensionsPart::
5900              AreExtensionsDisabledForProfile(browser_context));
5901
5902   factories->emplace(
5903       extensions::kExtensionScheme,
5904       extensions::CreateExtensionWorkerMainResourceURLLoaderFactory(
5905           browser_context));
5906 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
5907 }
5908
5909 void ChromeContentBrowserClient::
5910     RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories(
5911         content::BrowserContext* browser_context,
5912         NonNetworkURLLoaderFactoryMap* factories) {
5913   DCHECK(browser_context);
5914   DCHECK(factories);
5915
5916 #if !BUILDFLAG(IS_ANDROID)
5917   if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
5918           browser_context) &&
5919       !browser_context->ShutdownStarted()) {
5920     factories->emplace(
5921         chrome::kIsolatedAppScheme,
5922         web_app::IsolatedWebAppURLLoaderFactory::CreateForServiceWorker(
5923             browser_context));
5924   }
5925 #endif  // !BUILDFLAG(IS_ANDROID)
5926
5927 #if BUILDFLAG(ENABLE_EXTENSIONS)
5928   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
5929           browser_context)) {
5930     return;
5931   }
5932
5933   factories->emplace(
5934       extensions::kExtensionScheme,
5935       extensions::CreateExtensionServiceWorkerScriptURLLoaderFactory(
5936           browser_context));
5937 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
5938 }
5939
5940 namespace {
5941
5942 // The SpecialAccessFileURLLoaderFactory provided to the extension background
5943 // pages.  Checks with the ChildProcessSecurityPolicy to validate the file
5944 // access.
5945 class SpecialAccessFileURLLoaderFactory
5946     : public network::SelfDeletingURLLoaderFactory {
5947  public:
5948   // Returns mojo::PendingRemote to a newly constructed
5949   // SpecialAccessFileURLLoaderFactory.  The factory is self-owned - it will
5950   // delete itself once there are no more receivers (including the receiver
5951   // associated with the returned mojo::PendingRemote and the receivers bound by
5952   // the Clone method).
5953   static mojo::PendingRemote<network::mojom::URLLoaderFactory> Create(
5954       int child_id) {
5955     mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_remote;
5956
5957     // The SpecialAccessFileURLLoaderFactory will delete itself when there are
5958     // no more receivers - see the
5959     // network::SelfDeletingURLLoaderFactory::OnDisconnect method.
5960     new SpecialAccessFileURLLoaderFactory(
5961         child_id, pending_remote.InitWithNewPipeAndPassReceiver());
5962
5963     return pending_remote;
5964   }
5965
5966   SpecialAccessFileURLLoaderFactory(const SpecialAccessFileURLLoaderFactory&) =
5967       delete;
5968   SpecialAccessFileURLLoaderFactory& operator=(
5969       const SpecialAccessFileURLLoaderFactory&) = delete;
5970
5971  private:
5972   explicit SpecialAccessFileURLLoaderFactory(
5973       int child_id,
5974       mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver)
5975       : network::SelfDeletingURLLoaderFactory(std::move(factory_receiver)),
5976         child_id_(child_id) {}
5977
5978   // network::mojom::URLLoaderFactory:
5979   void CreateLoaderAndStart(
5980       mojo::PendingReceiver<network::mojom::URLLoader> loader,
5981       int32_t request_id,
5982       uint32_t options,
5983       const network::ResourceRequest& request,
5984       mojo::PendingRemote<network::mojom::URLLoaderClient> client,
5985       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
5986       override {
5987     if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL(
5988             child_id_, request.url)) {
5989       mojo::Remote<network::mojom::URLLoaderClient>(std::move(client))
5990           ->OnComplete(
5991               network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED));
5992       return;
5993     }
5994     content::CreateFileURLLoaderBypassingSecurityChecks(
5995         request, std::move(loader), std::move(client),
5996         /*observer=*/nullptr,
5997         /* allow_directory_listing */ true);
5998   }
5999
6000   int child_id_;
6001 };
6002
6003 #if BUILDFLAG(IS_CHROMEOS)
6004 bool IsSystemFeatureDisabled(policy::SystemFeature system_feature) {
6005   return policy::SystemFeaturesDisableListPolicyHandler::
6006       IsSystemFeatureDisabled(system_feature, g_browser_process->local_state());
6007 }
6008
6009 bool IsSystemFeatureURLDisabled(const GURL& url) {
6010   if (!url.SchemeIs(content::kChromeUIScheme) &&
6011       !url.SchemeIs(content::kChromeUIUntrustedScheme)) {
6012     return false;
6013   }
6014
6015   // chrome://os-settings/pwa.html shouldn't be replaced to let the settings app
6016   // installation complete successfully.
6017   if (url.DomainIs(chrome::kChromeUIOSSettingsHost) &&
6018       url.path() != "/pwa.html") {
6019     return IsSystemFeatureDisabled(policy::SystemFeature::kOsSettings);
6020   }
6021
6022   if (url.DomainIs(chrome::kChromeUISettingsHost)) {
6023     return IsSystemFeatureDisabled(policy::SystemFeature::kBrowserSettings);
6024   }
6025
6026 #if BUILDFLAG(IS_CHROMEOS_ASH)
6027   if (url.DomainIs(chrome::kChromeUIUntrustedCroshHost)) {
6028     return IsSystemFeatureDisabled(policy::SystemFeature::kCrosh);
6029   }
6030
6031   if (url.DomainIs(ash::kChromeUIScanningAppHost)) {
6032     return IsSystemFeatureDisabled(policy::SystemFeature::kScanning);
6033   }
6034
6035   if (url.DomainIs(ash::kChromeUICameraAppHost)) {
6036     return IsSystemFeatureDisabled(policy::SystemFeature::kCamera);
6037   }
6038
6039   if (url.DomainIs(ash::kChromeUIHelpAppHost)) {
6040     return IsSystemFeatureDisabled(policy::SystemFeature::kExplore);
6041   }
6042
6043   if (url.DomainIs(ash::kChromeUIMediaAppHost)) {
6044     return IsSystemFeatureDisabled(policy::SystemFeature::kGallery);
6045   }
6046
6047   if (url.DomainIs(chrome::kChromeUIUntrustedTerminalHost)) {
6048     return IsSystemFeatureDisabled(policy::SystemFeature::kTerminal);
6049   }
6050
6051 #endif
6052
6053   return false;
6054 }
6055 #endif
6056
6057 #if BUILDFLAG(ENABLE_EXTENSIONS)
6058 void InitializeFileURLLoaderFactoryForExtension(
6059     int render_process_id,
6060     content::BrowserContext* browser_context,
6061     const extensions::Extension* extension,
6062     ChromeContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories) {
6063   // Extensions with the necessary permissions get access to file:// URLs that
6064   // gets approval from ChildProcessSecurityPolicy. Keep this logic in sync with
6065   // ExtensionWebContentsObserver::RenderFrameCreated.
6066   Manifest::Type type = extension->GetType();
6067   if ((type == Manifest::TYPE_EXTENSION ||
6068        type == Manifest::TYPE_LEGACY_PACKAGED_APP) &&
6069       extensions::util::AllowFileAccess(extension->id(), browser_context)) {
6070     factories->emplace(
6071         url::kFileScheme,
6072         SpecialAccessFileURLLoaderFactory::Create(render_process_id));
6073   }
6074 }
6075
6076 void AddChromeSchemeFactories(
6077     int render_process_id,
6078     content::RenderFrameHost* frame_host,
6079     content::WebContents* web_contents,
6080     const extensions::Extension* extension,
6081     ChromeContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories) {
6082   Profile* profile =
6083       Profile::FromBrowserContext(web_contents->GetBrowserContext());
6084   InstantService* instant_service =
6085       InstantServiceFactory::GetForProfile(profile);
6086   // The test below matches when a remote 3P NTP is loaded. The effective
6087   // URL is chrome-search://remote-ntp. This is to allow the use of the NTP
6088   // public api and to embed most-visited tiles
6089   // (chrome-search://most-visited/title.html).
6090   //
6091   // InstantService might be null for some irregular profiles, e.g. the System
6092   // Profile.
6093   if (instant_service && instant_service->IsInstantProcess(render_process_id)) {
6094     factories->emplace(
6095         chrome::kChromeSearchScheme,
6096         content::CreateWebUIURLLoaderFactory(
6097             frame_host, chrome::kChromeSearchScheme,
6098             /*allowed_webui_hosts=*/base::flat_set<std::string>()));
6099   }
6100
6101   extensions::ChromeExtensionWebContentsObserver* web_observer =
6102       extensions::ChromeExtensionWebContentsObserver::FromWebContents(
6103           web_contents);
6104
6105   // There is nothing to do if no ChromeExtensionWebContentsObserver is attached
6106   // to the |web_contents| or no enabled extension exists.
6107   if (!web_observer || !extension)
6108     return;
6109
6110   std::vector<std::string> allowed_webui_hosts;
6111   // Support for chrome:// scheme if appropriate.
6112   if ((extension->is_extension() || extension->is_platform_app()) &&
6113       Manifest::IsComponentLocation(extension->location())) {
6114     // Components of chrome that are implemented as extensions or platform apps
6115     // are allowed to use chrome://resources/ and chrome://theme/ URLs.
6116     allowed_webui_hosts.emplace_back(content::kChromeUIResourcesHost);
6117     allowed_webui_hosts.emplace_back(chrome::kChromeUIThemeHost);
6118     // For testing purposes chrome://webui-test/ is also allowed.
6119     allowed_webui_hosts.emplace_back(chrome::kChromeUIWebUITestHost);
6120   }
6121   if (extension->is_extension() || extension->is_legacy_packaged_app() ||
6122       (extension->is_platform_app() &&
6123        Manifest::IsComponentLocation(extension->location()))) {
6124     // Extensions, legacy packaged apps, and component platform apps are allowed
6125     // to use chrome://favicon/, chrome://extension-icon/ and chrome://app-icon
6126     // URLs. Hosted apps are not allowed because they are served via web servers
6127     // (and are generally never given access to Chrome APIs).
6128     allowed_webui_hosts.emplace_back(chrome::kChromeUIExtensionIconHost);
6129     allowed_webui_hosts.emplace_back(chrome::kChromeUIFaviconHost);
6130     allowed_webui_hosts.emplace_back(chrome::kChromeUIAppIconHost);
6131   }
6132   if (!allowed_webui_hosts.empty()) {
6133     factories->emplace(content::kChromeUIScheme,
6134                        content::CreateWebUIURLLoaderFactory(
6135                            frame_host, content::kChromeUIScheme,
6136                            std::move(allowed_webui_hosts)));
6137   }
6138 }
6139 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
6140 }  // namespace
6141
6142 void ChromeContentBrowserClient::
6143     RegisterNonNetworkSubresourceURLLoaderFactories(
6144         int render_process_id,
6145         int render_frame_id,
6146         const absl::optional<url::Origin>& request_initiator_origin,
6147         NonNetworkURLLoaderFactoryMap* factories) {
6148 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \
6149     !BUILDFLAG(IS_ANDROID)
6150   content::RenderFrameHost* frame_host =
6151       RenderFrameHost::FromID(render_process_id, render_frame_id);
6152   WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host);
6153 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \
6154         // !BUILDFLAG(IS_ANDROID)
6155
6156 #if BUILDFLAG(IS_CHROMEOS_ASH)
6157   if (web_contents) {
6158     Profile* profile =
6159         Profile::FromBrowserContext(web_contents->GetBrowserContext());
6160     factories->emplace(
6161         content::kExternalFileScheme,
6162         ash::ExternalFileURLLoaderFactory::Create(profile, render_process_id));
6163   }
6164 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
6165
6166 #if !BUILDFLAG(IS_ANDROID)
6167   {
6168     content::BrowserContext* browser_context =
6169         content::RenderProcessHost::FromID(render_process_id)
6170             ->GetBrowserContext();
6171     DCHECK(browser_context);
6172     if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
6173             browser_context) &&
6174         !browser_context->ShutdownStarted()) {
6175       // TODO(crbug.com/1365848): Only register the factory if we are already
6176       // in an isolated storage partition.
6177
6178       if (frame_host != nullptr) {
6179         factories->emplace(
6180             chrome::kIsolatedAppScheme,
6181             web_app::IsolatedWebAppURLLoaderFactory::Create(
6182                 frame_host->GetFrameTreeNodeId(), browser_context));
6183       } else {
6184         factories->emplace(
6185             chrome::kIsolatedAppScheme,
6186             web_app::IsolatedWebAppURLLoaderFactory::CreateForServiceWorker(
6187                 browser_context));
6188       }
6189     }
6190   }
6191 #endif
6192
6193 #if BUILDFLAG(ENABLE_EXTENSIONS)
6194   content::BrowserContext* browser_context =
6195       content::RenderProcessHost::FromID(render_process_id)
6196           ->GetBrowserContext();
6197   if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile(
6198           browser_context))
6199     return;
6200
6201   factories->emplace(extensions::kExtensionScheme,
6202                      extensions::CreateExtensionURLLoaderFactory(
6203                          render_process_id, render_frame_id));
6204
6205   const extensions::Extension* extension = nullptr;
6206   if (request_initiator_origin != absl::nullopt) {
6207     extensions::ExtensionRegistry* registry =
6208         extensions::ExtensionRegistry::Get(
6209             Profile::FromBrowserContext(browser_context));
6210     DCHECK(registry);
6211     extension = registry->enabled_extensions().GetExtensionOrAppByURL(
6212         request_initiator_origin->GetURL());
6213   }
6214
6215   // For service worker contexts, we only allow file access. The remainder of
6216   // this code is used to allow extensions to access chrome:-scheme
6217   // resources, which we are moving away from.
6218   // TODO(crbug.com/1280411) Factories should not be created for unloaded
6219   // extensions.
6220   if (extension) {
6221     InitializeFileURLLoaderFactoryForExtension(
6222         render_process_id, browser_context, extension, factories);
6223   }
6224
6225   // This logic should match
6226   // ChromeExtensionWebContentsObserver::RenderFrameCreated.
6227   if (web_contents) {
6228     AddChromeSchemeFactories(render_process_id, frame_host, web_contents,
6229                              extension, factories);
6230   }
6231 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
6232 }
6233
6234 bool ChromeContentBrowserClient::WillCreateURLLoaderFactory(
6235     content::BrowserContext* browser_context,
6236     content::RenderFrameHost* frame,
6237     int render_process_id,
6238     URLLoaderFactoryType type,
6239     const url::Origin& request_initiator,
6240     absl::optional<int64_t> navigation_id,
6241     ukm::SourceIdObj ukm_source_id,
6242     mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
6243     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
6244         header_client,
6245     bool* bypass_redirect_checks,
6246     bool* disable_secure_dns,
6247     network::mojom::URLLoaderFactoryOverridePtr* factory_override,
6248     scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) {
6249   bool use_proxy = false;
6250
6251 #if BUILDFLAG(ENABLE_EXTENSIONS)
6252   auto* web_request_api =
6253       extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
6254           browser_context);
6255
6256   // NOTE: Some unit test environments do not initialize
6257   // BrowserContextKeyedAPI factories for e.g. WebRequest.
6258   if (web_request_api) {
6259     bool use_proxy_for_web_request =
6260         web_request_api->MaybeProxyURLLoaderFactory(
6261             browser_context, frame, render_process_id, type,
6262             std::move(navigation_id), ukm_source_id, factory_receiver,
6263             header_client, navigation_response_task_runner, request_initiator);
6264     if (bypass_redirect_checks)
6265       *bypass_redirect_checks = use_proxy_for_web_request;
6266     use_proxy |= use_proxy_for_web_request;
6267   }
6268 #endif
6269
6270   use_proxy |= signin::ProxyingURLLoaderFactory::MaybeProxyRequest(
6271       frame, type == URLLoaderFactoryType::kNavigation, request_initiator,
6272       factory_receiver);
6273
6274 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
6275   if (disable_secure_dns) {
6276     WebContents* web_contents = WebContents::FromRenderFrameHost(frame);
6277     *disable_secure_dns =
6278         web_contents &&
6279         captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents) &&
6280         captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents)
6281             ->is_captive_portal_window();
6282   }
6283 #endif
6284
6285   return use_proxy;
6286 }
6287
6288 std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
6289 ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
6290     content::NavigationUIData* navigation_ui_data,
6291     int frame_tree_node_id,
6292     int64_t navigation_id,
6293     scoped_refptr<base::SequencedTaskRunner> navigation_response_task_runner) {
6294   std::vector<std::unique_ptr<content::URLLoaderRequestInterceptor>>
6295       interceptors;
6296 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
6297   interceptors.push_back(
6298       std::make_unique<offline_pages::OfflinePageURLLoaderRequestInterceptor>(
6299           navigation_ui_data, frame_tree_node_id));
6300 #endif
6301
6302 #if BUILDFLAG(ENABLE_PDF)
6303   {
6304     std::unique_ptr<content::URLLoaderRequestInterceptor> pdf_interceptor =
6305         pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor(
6306             frame_tree_node_id, std::make_unique<ChromePdfStreamDelegate>());
6307     if (pdf_interceptor)
6308       interceptors.push_back(std::move(pdf_interceptor));
6309   }
6310 #endif
6311
6312   interceptors.push_back(std::make_unique<SearchPrefetchURLLoaderInterceptor>(
6313       frame_tree_node_id, navigation_id, navigation_response_task_runner));
6314
6315   auto https_upgrades_interceptor =
6316       HttpsUpgradesInterceptor::MaybeCreateInterceptor(frame_tree_node_id,
6317                                                        navigation_ui_data);
6318   if (https_upgrades_interceptor) {
6319     interceptors.push_back(std::move(https_upgrades_interceptor));
6320   }
6321
6322   return interceptors;
6323 }
6324
6325 content::ContentBrowserClient::URLLoaderRequestHandler
6326 ChromeContentBrowserClient::
6327     CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
6328         int frame_tree_node_id,
6329         const network::ResourceRequest& resource_request) {
6330   SearchPrefetchURLLoader::RequestHandler prefetch_handler =
6331       SearchPrefetchURLLoaderInterceptor::MaybeCreateLoaderForRequest(
6332           resource_request, frame_tree_node_id);
6333   return prefetch_handler;
6334 }
6335
6336 bool ChromeContentBrowserClient::WillInterceptWebSocket(
6337     content::RenderFrameHost* frame) {
6338 #if BUILDFLAG(ENABLE_EXTENSIONS)
6339   if (!frame) {
6340     return false;
6341   }
6342   const auto* web_request_api =
6343       extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
6344           frame->GetBrowserContext());
6345
6346   // NOTE: Some unit test environments do not initialize
6347   // BrowserContextKeyedAPI factories for e.g. WebRequest.
6348   if (!web_request_api)
6349     return false;
6350   return (web_request_api->MayHaveProxies() ||
6351           web_request_api->MayHaveWebsocketProxiesForExtensionTelemetry());
6352 #else
6353   return false;
6354 #endif
6355 }
6356
6357 void ChromeContentBrowserClient::CreateWebSocket(
6358     content::RenderFrameHost* frame,
6359     WebSocketFactory factory,
6360     const GURL& url,
6361     const net::SiteForCookies& site_for_cookies,
6362     const absl::optional<std::string>& user_agent,
6363     mojo::PendingRemote<network::mojom::WebSocketHandshakeClient>
6364         handshake_client) {
6365 #if BUILDFLAG(ENABLE_EXTENSIONS)
6366   // TODO(crbug.com/1243518): Request w/o a frame also should be proxied.
6367   if (!frame) {
6368     return;
6369   }
6370   auto* web_request_api =
6371       extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
6372           frame->GetBrowserContext());
6373
6374   DCHECK(web_request_api);
6375   web_request_api->ProxyWebSocket(frame, std::move(factory), url,
6376                                   site_for_cookies, user_agent,
6377                                   std::move(handshake_client));
6378 #endif
6379 }
6380
6381 void ChromeContentBrowserClient::WillCreateWebTransport(
6382     int process_id,
6383     int frame_routing_id,
6384     const GURL& url,
6385     const url::Origin& initiator_origin,
6386     mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
6387         handshake_client,
6388     WillCreateWebTransportCallback callback) {
6389 #if BUILDFLAG(SAFE_BROWSING_AVAILABLE)
6390   content::RenderFrameHost* frame =
6391       content::RenderFrameHost::FromID(process_id, frame_routing_id);
6392   if (frame) {
6393     int frame_tree_node_id = frame->GetFrameTreeNodeId();
6394     content::WebContents* web_contents =
6395         content::WebContents::FromFrameTreeNodeId(frame_tree_node_id);
6396     DCHECK(web_contents);
6397     Profile* profile =
6398         Profile::FromBrowserContext(web_contents->GetBrowserContext());
6399     DCHECK(profile);
6400     auto checker = std::make_unique<safe_browsing::WebApiHandshakeChecker>(
6401         base::BindOnce(
6402             &ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate,
6403             base::Unretained(this),
6404             safe_browsing::IsSafeBrowsingEnabled(*profile->GetPrefs()),
6405             /*should_check_on_sb_disabled=*/false,
6406             safe_browsing::GetURLAllowlistByPolicy(profile->GetPrefs())),
6407         base::BindRepeating(&content::WebContents::FromFrameTreeNodeId,
6408                             frame_tree_node_id),
6409         frame_tree_node_id);
6410     auto* raw_checker = checker.get();
6411     raw_checker->Check(
6412         url,
6413         base::BindOnce(
6414             &ChromeContentBrowserClient::SafeBrowsingWebApiHandshakeChecked,
6415             weak_factory_.GetWeakPtr(), std::move(checker), process_id,
6416             frame_routing_id, url, initiator_origin,
6417             std::move(handshake_client), std::move(callback)));
6418     return;
6419   }
6420 #endif
6421   MaybeInterceptWebTransport(process_id, frame_routing_id, url,
6422                              initiator_origin, std::move(handshake_client),
6423                              std::move(callback));
6424 }
6425
6426 void ChromeContentBrowserClient::SafeBrowsingWebApiHandshakeChecked(
6427     std::unique_ptr<safe_browsing::WebApiHandshakeChecker> checker,
6428     int process_id,
6429     int frame_routing_id,
6430     const GURL& url,
6431     const url::Origin& initiator_origin,
6432     mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
6433         handshake_client,
6434     WillCreateWebTransportCallback callback,
6435     safe_browsing::WebApiHandshakeChecker::CheckResult result) {
6436   if (result == safe_browsing::WebApiHandshakeChecker::CheckResult::kProceed) {
6437     MaybeInterceptWebTransport(process_id, frame_routing_id, url,
6438                                initiator_origin, std::move(handshake_client),
6439                                std::move(callback));
6440   } else {
6441     std::move(callback).Run(std::move(handshake_client),
6442                             network::mojom::WebTransportError::New(
6443                                 net::ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
6444                                 "SafeBrowsing check failed", false));
6445   }
6446 }
6447
6448 void ChromeContentBrowserClient::MaybeInterceptWebTransport(
6449     int process_id,
6450     int frame_routing_id,
6451     const GURL& url,
6452     const url::Origin& initiator_origin,
6453     mojo::PendingRemote<network::mojom::WebTransportHandshakeClient>
6454         handshake_client,
6455     WillCreateWebTransportCallback callback) {
6456 #if BUILDFLAG(ENABLE_EXTENSIONS)
6457   DCHECK_CURRENTLY_ON(BrowserThread::UI);
6458   // TODO(1243518): Add a unit test which calls
6459   // ChromeContentBrowserClient::WillCreateWebTransport() with invalid process
6460   // id and routing id.
6461   auto* render_process_host = content::RenderProcessHost::FromID(process_id);
6462   if (!render_process_host) {
6463     std::move(callback).Run(std::move(handshake_client), absl::nullopt);
6464     return;
6465   }
6466   content::BrowserContext* browser_context =
6467       render_process_host->GetBrowserContext();
6468   auto* web_request_api =
6469       extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
6470           browser_context);
6471   // NOTE: Some unit test environments do not initialize BrowserContextKeyedAPI
6472   // factories like WebRequestAPI.
6473   if (!web_request_api) {
6474     std::move(callback).Run(std::move(handshake_client), absl::nullopt);
6475     return;
6476   }
6477   web_request_api->ProxyWebTransport(
6478       *render_process_host, frame_routing_id, url, initiator_origin,
6479       std::move(handshake_client), std::move(callback));
6480 #else
6481   std::move(callback).Run(std::move(handshake_client), absl::nullopt);
6482 #endif
6483 }
6484
6485 bool ChromeContentBrowserClient::WillCreateRestrictedCookieManager(
6486     network::mojom::RestrictedCookieManagerRole role,
6487     content::BrowserContext* browser_context,
6488     const url::Origin& origin,
6489     const net::IsolationInfo& isolation_info,
6490     bool is_service_worker,
6491     int process_id,
6492     int routing_id,
6493     mojo::PendingReceiver<network::mojom::RestrictedCookieManager>* receiver) {
6494   DCHECK_CURRENTLY_ON(BrowserThread::UI);
6495 #if BUILDFLAG(ENABLE_EXTENSIONS)
6496   if (origin.scheme() == extensions::kExtensionScheme) {
6497     DCHECK_EQ(network::mojom::RestrictedCookieManagerRole::SCRIPT, role);
6498     extensions::ChromeExtensionCookies::Get(browser_context)
6499         ->CreateRestrictedCookieManager(origin, isolation_info,
6500                                         std::move(*receiver));
6501     return true;
6502   }
6503 #endif
6504   return false;
6505 }
6506
6507 void ChromeContentBrowserClient::OnNetworkServiceCreated(
6508     network::mojom::NetworkService* network_service) {
6509   PrefService* local_state;
6510   if (g_browser_process) {
6511     DCHECK(g_browser_process->local_state());
6512     local_state = g_browser_process->local_state();
6513   } else {
6514     DCHECK(startup_data_.chrome_feature_list_creator()->local_state());
6515     local_state = startup_data_.chrome_feature_list_creator()->local_state();
6516   }
6517
6518   // Create SystemNetworkContextManager if it has not been created yet. We need
6519   // to set up global NetworkService state before anything else uses it and this
6520   // is the first opportunity to initialize SystemNetworkContextManager with the
6521   // NetworkService.
6522   if (!SystemNetworkContextManager::HasInstance())
6523     SystemNetworkContextManager::CreateInstance(local_state);
6524
6525   SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated(
6526       network_service);
6527
6528 #if !BUILDFLAG(IS_ANDROID)
6529   if (task_manager::TaskManagerImpl::IsCreated() &&
6530       task_manager::TaskManagerImpl::GetInstance()->is_running()) {
6531     network_service->EnableDataUseUpdates(true);
6532   }
6533 #endif
6534 }
6535
6536 void ChromeContentBrowserClient::ConfigureNetworkContextParams(
6537     content::BrowserContext* context,
6538     bool in_memory,
6539     const base::FilePath& relative_partition_path,
6540     network::mojom::NetworkContextParams* network_context_params,
6541     cert_verifier::mojom::CertVerifierCreationParams*
6542         cert_verifier_creation_params) {
6543   ProfileNetworkContextService* service =
6544       ProfileNetworkContextServiceFactory::GetForContext(context);
6545   if (service) {
6546     service->ConfigureNetworkContextParams(in_memory, relative_partition_path,
6547                                            network_context_params,
6548                                            cert_verifier_creation_params);
6549   } else {
6550     // Set default params.
6551     network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
6552     network_context_params->accept_language = GetApplicationLocale();
6553   }
6554 }
6555
6556 std::vector<base::FilePath>
6557 ChromeContentBrowserClient::GetNetworkContextsParentDirectory() {
6558   DCHECK(!network_contexts_parent_directory_.empty());
6559   return network_contexts_parent_directory_;
6560 }
6561
6562 base::Value::Dict ChromeContentBrowserClient::GetNetLogConstants() {
6563   return net_log::GetPlatformConstantsForNetLog(
6564       base::CommandLine::ForCurrentProcess()->GetCommandLineString(),
6565       chrome::GetChannelName(chrome::WithExtendedStable(true)));
6566 }
6567
6568 bool ChromeContentBrowserClient::AllowRenderingMhtmlOverHttp(
6569     content::NavigationUIData* navigation_ui_data) {
6570 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
6571   // It is OK to load the saved offline copy, in MHTML format.
6572   ChromeNavigationUIData* chrome_navigation_ui_data =
6573       static_cast<ChromeNavigationUIData*>(navigation_ui_data);
6574   if (!chrome_navigation_ui_data)
6575     return false;
6576   offline_pages::OfflinePageNavigationUIData* offline_page_data =
6577       chrome_navigation_ui_data->GetOfflinePageNavigationUIData();
6578   return offline_page_data && offline_page_data->is_offline_page();
6579 #else
6580   return false;
6581 #endif
6582 }
6583
6584 bool ChromeContentBrowserClient::ShouldForceDownloadResource(
6585     content::BrowserContext* browser_context,
6586     const GURL& url,
6587     const std::string& mime_type) {
6588 #if BUILDFLAG(ENABLE_EXTENSIONS)
6589   // Special-case user scripts to get downloaded instead of viewed.
6590   if (extensions::UserScript::IsURLUserScript(url, mime_type)) {
6591     return true;
6592   }
6593
6594 #if BUILDFLAG(IS_CHROMEOS)
6595   // QuickOffice file interception is deprecated. If QuickOffice would
6596   // have intercepted this file and this feature is disabled, download
6597   // it instead.
6598   if (browser_context) {
6599     Profile* profile = Profile::FromBrowserContext(browser_context);
6600     bool force_download = profile->GetPrefs()->GetBoolean(
6601         quickoffice::kQuickOfficeForceFileDownloadEnabled);
6602
6603     if (base::FeatureList::IsEnabled(features::kQuickOfficeForceFileDownload) &&
6604         force_download) {
6605       std::string extension_id =
6606           PluginUtils::GetExtensionIdForMimeType(browser_context, mime_type);
6607
6608       if (extension_misc::IsQuickOfficeExtension(extension_id)) {
6609         return true;
6610       }
6611     }
6612   }
6613 #endif  // BUILDFLAG(IS_CHROMEOS)
6614 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
6615   return false;
6616 }
6617
6618 content::BluetoothDelegate* ChromeContentBrowserClient::GetBluetoothDelegate() {
6619   if (!bluetooth_delegate_) {
6620     bluetooth_delegate_ = std::make_unique<permissions::BluetoothDelegateImpl>(
6621         std::make_unique<ChromeBluetoothDelegateImplClient>());
6622   }
6623   return bluetooth_delegate_.get();
6624 }
6625
6626 content::UsbDelegate* ChromeContentBrowserClient::GetUsbDelegate() {
6627   if (!usb_delegate_)
6628     usb_delegate_ = std::make_unique<ChromeUsbDelegate>();
6629   return usb_delegate_.get();
6630 }
6631
6632 content::PrivateNetworkDeviceDelegate*
6633 ChromeContentBrowserClient::GetPrivateNetworkDeviceDelegate() {
6634   if (!private_network_device_delegate_) {
6635     private_network_device_delegate_ =
6636         std::make_unique<ChromePrivateNetworkDeviceDelegate>();
6637   }
6638   return private_network_device_delegate_.get();
6639 }
6640
6641 #if !BUILDFLAG(IS_ANDROID)
6642 void ChromeContentBrowserClient::CreateDeviceInfoService(
6643     content::RenderFrameHost* render_frame_host,
6644     mojo::PendingReceiver<blink::mojom::DeviceAPIService> receiver) {
6645   DCHECK(render_frame_host);
6646   DeviceServiceImpl::Create(render_frame_host, std::move(receiver));
6647 }
6648
6649 void ChromeContentBrowserClient::CreateManagedConfigurationService(
6650     content::RenderFrameHost* render_frame_host,
6651     mojo::PendingReceiver<blink::mojom::ManagedConfigurationService> receiver) {
6652   DCHECK(render_frame_host);
6653   ManagedConfigurationServiceImpl::Create(render_frame_host,
6654                                           std::move(receiver));
6655 }
6656
6657 content::SerialDelegate* ChromeContentBrowserClient::GetSerialDelegate() {
6658   if (!serial_delegate_)
6659     serial_delegate_ = std::make_unique<ChromeSerialDelegate>();
6660   return serial_delegate_.get();
6661 }
6662
6663 content::HidDelegate* ChromeContentBrowserClient::GetHidDelegate() {
6664   if (!hid_delegate_)
6665     hid_delegate_ = std::make_unique<ChromeHidDelegate>();
6666   return hid_delegate_.get();
6667 }
6668
6669 content::DirectSocketsDelegate*
6670 ChromeContentBrowserClient::GetDirectSocketsDelegate() {
6671   if (!direct_sockets_delegate_) {
6672     direct_sockets_delegate_ = std::make_unique<ChromeDirectSocketsDelegate>();
6673   }
6674   return direct_sockets_delegate_.get();
6675 }
6676
6677 content::WebAuthenticationDelegate*
6678 ChromeContentBrowserClient::GetWebAuthenticationDelegate() {
6679   if (!web_authentication_delegate_) {
6680     web_authentication_delegate_ =
6681         std::make_unique<ChromeWebAuthenticationDelegate>();
6682   }
6683   return web_authentication_delegate_.get();
6684 }
6685
6686 std::unique_ptr<content::AuthenticatorRequestClientDelegate>
6687 ChromeContentBrowserClient::GetWebAuthenticationRequestDelegate(
6688     content::RenderFrameHost* render_frame_host) {
6689   return AuthenticatorRequestScheduler::CreateRequestDelegate(
6690       render_frame_host);
6691 }
6692 #endif
6693
6694 std::unique_ptr<net::ClientCertStore>
6695 ChromeContentBrowserClient::CreateClientCertStore(
6696     content::BrowserContext* browser_context) {
6697   return ProfileNetworkContextServiceFactory::GetForContext(browser_context)
6698       ->CreateClientCertStore();
6699 }
6700
6701 std::unique_ptr<content::LoginDelegate>
6702 ChromeContentBrowserClient::CreateLoginDelegate(
6703     const net::AuthChallengeInfo& auth_info,
6704     content::WebContents* web_contents,
6705     const content::GlobalRequestID& request_id,
6706     bool is_request_for_primary_main_frame,
6707     const GURL& url,
6708     scoped_refptr<net::HttpResponseHeaders> response_headers,
6709     bool first_auth_attempt,
6710     LoginAuthRequiredCallback auth_required_callback) {
6711 #if BUILDFLAG(IS_CHROMEOS)
6712   // Negotiate challenge is handled via GSSAPI library, which can not receive
6713   // external credentials. However, on ChromeOS we can suggest the user to
6714   // create a TGT using their credentials. Note that the credentials are NOT
6715   // passed to the browser and everything happens on OS level, hence we return
6716   // nullptr instead of LoginDelegate to fail authentication. (See b/260522530).
6717   if (base::FeatureList::IsEnabled(net::features::kKerberosInBrowserRedirect) &&
6718       auth_info.scheme ==
6719           net::HttpAuth::SchemeToString(net::HttpAuth::AUTH_SCHEME_NEGOTIATE)) {
6720 #if BUILDFLAG(IS_CHROMEOS_ASH)
6721     ash::KerberosInBrowserDialog::Show();
6722 #else
6723     // Requests to show Kerberos ui via crosapi mojo call.
6724     chromeos::LacrosService::Get()
6725         ->GetRemote<crosapi::mojom::KerberosInBrowser>()
6726         ->ShowKerberosInBrowserDialog();
6727 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
6728     return nullptr;
6729   }
6730 #endif  // BUILDFLAG(IS_CHROMEOS)
6731
6732 #if BUILDFLAG(IS_CHROMEOS_ASH)
6733   auto* system_proxy_manager = ash::SystemProxyManager::Get();
6734   // For Managed Guest Session and Kiosk devices, the credentials configured
6735   // via the policy SystemProxySettings may be used for proxy authentication.
6736   // Note: |system_proxy_manager| may be missing in tests.
6737   if (system_proxy_manager && system_proxy_manager->CanUsePolicyCredentials(
6738                                   auth_info, first_auth_attempt)) {
6739     return system_proxy_manager->CreateLoginDelegate(
6740         std::move(auth_required_callback));
6741   }
6742 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
6743
6744   // For subresources, create a LoginHandler directly, which may show a login
6745   // prompt to the user. Main frame resources go through LoginTabHelper, which
6746   // manages a more complicated flow to avoid confusion about which website is
6747   // showing the prompt.
6748   if (is_request_for_primary_main_frame) {
6749     LoginTabHelper::CreateForWebContents(web_contents);
6750     return LoginTabHelper::FromWebContents(web_contents)
6751         ->CreateAndStartMainFrameLoginDelegate(
6752             auth_info, web_contents, request_id, url, response_headers,
6753             std::move(auth_required_callback));
6754   }
6755   std::unique_ptr<LoginHandler> login_handler = LoginHandler::Create(
6756       auth_info, web_contents, std::move(auth_required_callback));
6757   login_handler->StartSubresource(request_id, url, response_headers);
6758   return login_handler;
6759 }
6760
6761 bool ChromeContentBrowserClient::HandleExternalProtocol(
6762     const GURL& url,
6763     content::WebContents::Getter web_contents_getter,
6764     int frame_tree_node_id,
6765     content::NavigationUIData* navigation_data,
6766     bool is_primary_main_frame,
6767     bool is_in_fenced_frame_tree,
6768     network::mojom::WebSandboxFlags sandbox_flags,
6769     ui::PageTransition page_transition,
6770     bool has_user_gesture,
6771     const absl::optional<url::Origin>& initiating_origin,
6772     content::RenderFrameHost* initiator_document,
6773     mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) {
6774 #if BUILDFLAG(ENABLE_EXTENSIONS)
6775   // External protocols are disabled for guests. An exception is made for the
6776   // "mailto" protocol, so that pages that utilize it work properly in a
6777   // WebView.
6778   ChromeNavigationUIData* chrome_data =
6779       static_cast<ChromeNavigationUIData*>(navigation_data);
6780   if ((chrome_data &&
6781        chrome_data->GetExtensionNavigationUIData()->is_web_view()) &&
6782       !url.SchemeIs(url::kMailToScheme)) {
6783     return false;
6784   }
6785 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
6786
6787 #if BUILDFLAG(IS_ANDROID)
6788   // Main frame external protocols are handled by
6789   // InterceptNavigationResourceThrottle.
6790   if (is_primary_main_frame)
6791     return false;
6792 #endif  // defined(ANDROID)
6793
6794   auto weak_initiator_document = initiator_document
6795                                      ? initiator_document->GetWeakDocumentPtr()
6796                                      : content::WeakDocumentPtr();
6797
6798 #if BUILDFLAG(IS_ANDROID)
6799   // For Android this is always called on the UI thread.
6800   CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
6801
6802   // Called synchronously so we can populate the |out_factory| param.
6803   LaunchURL(weak_factory_.GetWeakPtr(), url, std::move(web_contents_getter),
6804             page_transition, is_primary_main_frame, is_in_fenced_frame_tree,
6805             sandbox_flags, has_user_gesture, initiating_origin,
6806             std::move(weak_initiator_document), out_factory);
6807 #else
6808   // TODO(crbug.com/1394838): Figure out why this was initially made async, and,
6809   // if possible, unify with the sync path above.
6810   content::GetUIThreadTaskRunner({})->PostTask(
6811       FROM_HERE,
6812       base::BindOnce(&LaunchURL, weak_factory_.GetWeakPtr(), url,
6813                      std::move(web_contents_getter), page_transition,
6814                      is_primary_main_frame, is_in_fenced_frame_tree,
6815                      sandbox_flags, has_user_gesture, initiating_origin,
6816                      std::move(weak_initiator_document)));
6817 #endif
6818   return true;
6819 }
6820
6821 std::unique_ptr<content::VideoOverlayWindow>
6822 ChromeContentBrowserClient::CreateWindowForVideoPictureInPicture(
6823     content::VideoPictureInPictureWindowController* controller) {
6824   // Note: content::VideoOverlayWindow::Create() is defined by platform-specific
6825   // implementation in chrome/browser/ui/views. This layering hack, which goes
6826   // through //content and ContentBrowserClient, allows us to work around the
6827   // dependency constraints that disallow directly calling
6828   // chrome/browser/ui/views code either from here or from other code in
6829   // chrome/browser.
6830   return content::VideoOverlayWindow::Create(controller);
6831 }
6832
6833 void ChromeContentBrowserClient::RegisterRendererPreferenceWatcher(
6834     content::BrowserContext* browser_context,
6835     mojo::PendingRemote<blink::mojom::RendererPreferenceWatcher> watcher) {
6836   Profile* profile = Profile::FromBrowserContext(browser_context);
6837   if (PrefWatcher* pref_watcher = PrefWatcher::Get(profile))
6838     pref_watcher->RegisterRendererPreferenceWatcher(std::move(watcher));
6839 }
6840
6841 // Static; handles rewriting Web UI URLs.
6842 bool ChromeContentBrowserClient::HandleWebUI(
6843     GURL* url,
6844     content::BrowserContext* browser_context) {
6845   DCHECK(browser_context);
6846
6847   // Rewrite chrome://help to chrome://settings/help.
6848   if (url->SchemeIs(content::kChromeUIScheme) &&
6849       url->host() == chrome::kChromeUIHelpHost) {
6850     *url = ReplaceURLHostAndPath(*url, chrome::kChromeUISettingsHost,
6851                                  chrome::kChromeUIHelpHost);
6852   }
6853
6854 #if !BUILDFLAG(IS_ANDROID)
6855   if (base::FeatureList::IsEnabled(privacy_sandbox::kPrivacySandboxSettings4)) {
6856     // Redirect to the new version of privacy sandbox settings.
6857     if (url->SchemeIs(content::kChromeUIScheme) &&
6858         url->host() == chrome::kChromeUISettingsHost) {
6859       if (url->path() == chrome::kPrivacySandboxSubPagePath) {
6860         GURL::Replacements replacements;
6861         replacements.SetPathStr(chrome::kAdPrivacySubPagePath);
6862         *url = url->ReplaceComponents(replacements);
6863         UMA_HISTOGRAM_BOOLEAN("Settings.PrivacySandbox.DeprecatedRedirect",
6864                               true);
6865       } else if (url->path() == chrome::kAdPrivacySubPagePath) {
6866         // Log un-redirected navigations to the page as well to provide context
6867         // for the raw number of redirects.
6868         UMA_HISTOGRAM_BOOLEAN("Settings.PrivacySandbox.DeprecatedRedirect",
6869                               false);
6870       }
6871     }
6872   }
6873   if (base::FeatureList::IsEnabled(
6874           features::kPerformanceSettingsPreloadingSubpage)) {
6875     // Redirect from the preloading sub-page to the performance page.
6876     if (url->SchemeIs(content::kChromeUIScheme) &&
6877         url->host() == chrome::kChromeUISettingsHost &&
6878         url->path() == chrome::kPreloadingSubPagePath) {
6879       GURL::Replacements replacements;
6880       replacements.SetPathStr(chrome::kPerformanceSubPagePath);
6881       *url = url->ReplaceComponents(replacements);
6882       UMA_HISTOGRAM_BOOLEAN("Settings.Preloading.DeprecatedRedirect", true);
6883     } else if (url->path() == chrome::kPerformanceSubPagePath) {
6884       UMA_HISTOGRAM_BOOLEAN("Settings.Preloading.DeprecatedRedirect", false);
6885     }
6886   }
6887   Profile* profile = Profile::FromBrowserContext(browser_context);
6888   auto* tracking_protection_settings =
6889       TrackingProtectionSettingsFactory::GetForProfile(profile);
6890   if (tracking_protection_settings &&
6891       tracking_protection_settings->IsTrackingProtection3pcdEnabled()) {
6892     // Redirect from cookies to trackingProtection in experiment.
6893     if (url->SchemeIs(content::kChromeUIScheme) &&
6894         url->host() == chrome::kChromeUISettingsHost &&
6895         url->path() == chrome::kCookiesSubPagePath) {
6896       GURL::Replacements replacements;
6897       replacements.SetPathStr(chrome::kTrackingProtectionSubPagePath);
6898       *url = url->ReplaceComponents(replacements);
6899       UMA_HISTOGRAM_BOOLEAN("Settings.TrackingProtection.Redirect", true);
6900     } else if (url->path() == chrome::kTrackingProtectionSubPagePath) {
6901       UMA_HISTOGRAM_BOOLEAN("Settings.TrackingProtection.Redirect", false);
6902     }
6903   } else {
6904     // Redirect from trackingProtection to cookies outside experiment.
6905     if (url->SchemeIs(content::kChromeUIScheme) &&
6906         url->host() == chrome::kChromeUISettingsHost &&
6907         url->path() == chrome::kTrackingProtectionSubPagePath) {
6908       GURL::Replacements replacements;
6909       replacements.SetPathStr(chrome::kCookiesSubPagePath);
6910       *url = url->ReplaceComponents(replacements);
6911     }
6912   }
6913 #endif
6914
6915 #if BUILDFLAG(IS_WIN)
6916   // TODO(crbug.com/1003960): Remove when issue is resolved.
6917   if (url->SchemeIs(content::kChromeUIScheme) &&
6918       url->host() == chrome::kChromeUIWelcomeWin10Host) {
6919     *url =
6920         ReplaceURLHostAndPath(*url, chrome::kChromeUIWelcomeHost, url->path());
6921     return true;
6922   }
6923 #endif  // BUILDFLAG(IS_WIN)
6924
6925   if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL(
6926           browser_context, *url) &&
6927       !content::WebUIConfigMap::GetInstance().GetConfig(browser_context,
6928                                                         *url)) {
6929     return false;
6930   }
6931
6932 #if BUILDFLAG(IS_CHROMEOS_ASH)
6933   // Special case : in ChromeOS in Guest mode bookmarks and history are
6934   // disabled for security reasons. New tab page explains the reasons, so
6935   // we redirect user to new tab page.
6936   if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
6937     if (url->SchemeIs(content::kChromeUIScheme) &&
6938         (url->DomainIs(chrome::kChromeUIBookmarksHost) ||
6939          url->DomainIs(chrome::kChromeUIHistoryHost))) {
6940       // Rewrite with new tab URL
6941       *url = GURL(chrome::kChromeUINewTabURL);
6942     }
6943   }
6944 #endif
6945
6946 #if BUILDFLAG(IS_CHROMEOS)
6947   if (IsSystemFeatureURLDisabled(*url)) {
6948     *url = GURL(chrome::kChromeUIAppDisabledURL);
6949     return true;
6950   }
6951 #endif
6952
6953   return true;
6954 }
6955
6956 #if BUILDFLAG(IS_CHROMEOS)
6957 content::SmartCardDelegate* ChromeContentBrowserClient::GetSmartCardDelegate(
6958     content::BrowserContext* browser_context) {
6959   if (!smart_card_delegate_) {
6960     smart_card_delegate_ = std::make_unique<ChromeOsSmartCardDelegate>();
6961   }
6962   return smart_card_delegate_.get();
6963 }
6964 #endif
6965
6966 bool ChromeContentBrowserClient::ShowPaymentHandlerWindow(
6967     content::BrowserContext* browser_context,
6968     const GURL& url,
6969     base::OnceCallback<void(bool, int, int)> callback) {
6970 #if BUILDFLAG(IS_ANDROID)
6971   return false;
6972 #else
6973   payments::PaymentRequestDisplayManagerFactory::GetInstance()
6974       ->GetForBrowserContext(browser_context)
6975       ->ShowPaymentHandlerWindow(url, std::move(callback));
6976   return true;
6977 #endif
6978 }
6979
6980 // static
6981 bool ChromeContentBrowserClient::HandleWebUIReverse(
6982     GURL* url,
6983     content::BrowserContext* browser_context) {
6984 #if BUILDFLAG(IS_WIN)
6985   // TODO(crbug.com/1003960): Remove when issue is resolved.
6986   // No need to actually reverse-rewrite the URL, but return true to update the
6987   // displayed URL when rewriting chrome://welcome-win10 to chrome://welcome.
6988   if (url->SchemeIs(content::kChromeUIScheme) &&
6989       url->host() == chrome::kChromeUIWelcomeHost) {
6990     return true;
6991   }
6992 #endif  // BUILDFLAG(IS_WIN)
6993
6994 #if !BUILDFLAG(IS_ANDROID)
6995   // TODO(crbug.com/1420597): Remove this after feature is launched.
6996   // No need to actually reverse-rewrite the URL, but return true to update the
6997   // displayed URL when rewriting chrome://settings/passwords to
6998   // chrome://password-manager.
6999   if (url->SchemeIs(content::kChromeUIScheme) &&
7000       url->DomainIs(password_manager::kChromeUIPasswordManagerHost)) {
7001     return true;
7002   }
7003 #endif
7004
7005   // No need to actually reverse-rewrite the URL, but return true to update the
7006   // displayed URL when rewriting chrome://help to chrome://settings/help.
7007   return url->SchemeIs(content::kChromeUIScheme) &&
7008          url->host() == chrome::kChromeUISettingsHost;
7009 }
7010
7011 const ui::NativeTheme* ChromeContentBrowserClient::GetWebTheme() const {
7012   return ui::NativeTheme::GetInstanceForWeb();
7013 }
7014
7015 void ChromeContentBrowserClient::AddExtraPart(
7016     ChromeContentBrowserClientParts* part) {
7017   extra_parts_.push_back(base::WrapUnique(part));
7018 }
7019
7020 scoped_refptr<safe_browsing::UrlCheckerDelegate>
7021 ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate(
7022     bool safe_browsing_enabled_for_profile,
7023     bool should_check_on_sb_disabled,
7024     const std::vector<std::string>& allowlist_domains) {
7025   DCHECK_CURRENTLY_ON(
7026       base::FeatureList::IsEnabled(safe_browsing::kSafeBrowsingOnUIThread)
7027           ? content::BrowserThread::UI
7028           : content::BrowserThread::IO);
7029
7030   // Should not bypass safe browsing check if the check is for enterprise
7031   // lookup.
7032   if (!safe_browsing_enabled_for_profile && !should_check_on_sb_disabled)
7033     return nullptr;
7034
7035   // |safe_browsing_service_| may be unavailable in tests.
7036   if (safe_browsing_service_ && !safe_browsing_url_checker_delegate_) {
7037     safe_browsing_url_checker_delegate_ =
7038         base::MakeRefCounted<safe_browsing::UrlCheckerDelegateImpl>(
7039             safe_browsing_service_->database_manager(),
7040             safe_browsing_service_->ui_manager());
7041   }
7042
7043   // Update allowlist domains.
7044   if (safe_browsing_url_checker_delegate_) {
7045     safe_browsing_url_checker_delegate_->SetPolicyAllowlistDomains(
7046         allowlist_domains);
7047   }
7048
7049   return safe_browsing_url_checker_delegate_;
7050 }
7051
7052 safe_browsing::RealTimeUrlLookupServiceBase*
7053 ChromeContentBrowserClient::GetUrlLookupService(
7054     content::BrowserContext* browser_context,
7055     bool is_enterprise_lookup_enabled,
7056     bool is_consumer_lookup_enabled) {
7057   // |safe_browsing_service_| may be unavailable in tests.
7058   if (!safe_browsing_service_) {
7059     return nullptr;
7060   }
7061
7062   Profile* profile = Profile::FromBrowserContext(browser_context);
7063
7064 #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL)
7065   if (is_enterprise_lookup_enabled) {
7066     return safe_browsing::ChromeEnterpriseRealTimeUrlLookupServiceFactory::
7067         GetForProfile(profile);
7068   }
7069 #endif
7070
7071   if (is_consumer_lookup_enabled) {
7072     return safe_browsing::RealTimeUrlLookupServiceFactory::GetForProfile(
7073         profile);
7074   }
7075   return nullptr;
7076 }
7077
7078 void ChromeContentBrowserClient::ReportLegacyTechEvent(
7079     content::RenderFrameHost* render_frame_host,
7080     const std::string type,
7081     const GURL& url,
7082     const std::string& filename,
7083     uint64_t line,
7084     uint64_t column) {
7085   WebContents* web_contents =
7086       WebContents::FromRenderFrameHost(render_frame_host);
7087   DCHECK(web_contents);
7088   Profile* profile =
7089       Profile::FromBrowserContext(web_contents->GetBrowserContext());
7090   if (!profile) {
7091     return;
7092   }
7093   enterprise_reporting::LegacyTechServiceFactory::GetForProfile(profile)
7094       ->ReportEvent(type, url, filename, line, column);
7095 }
7096
7097 bool ChromeContentBrowserClient::CanAcceptUntrustedExchangesIfNeeded() {
7098   // We require --user-data-dir flag too so that no dangerous changes are made
7099   // in the user's regular profile.
7100   return base::CommandLine::ForCurrentProcess()->HasSwitch(
7101       switches::kUserDataDir);
7102 }
7103
7104 void ChromeContentBrowserClient::OnNetworkServiceDataUseUpdate(
7105     content::GlobalRenderFrameHostId render_frame_host_id,
7106     int32_t network_traffic_annotation_id_hash,
7107     int64_t recv_bytes,
7108     int64_t sent_bytes) {
7109 #if !BUILDFLAG(IS_ANDROID)
7110   task_manager::TaskManagerInterface::UpdateAccumulatedStatsNetworkForRoute(
7111       render_frame_host_id, recv_bytes, sent_bytes);
7112 #endif
7113 }
7114
7115 base::FilePath
7116 ChromeContentBrowserClient::GetSandboxedStorageServiceDataDirectory() {
7117   if (!g_browser_process || !g_browser_process->profile_manager())
7118     return base::FilePath();
7119   return g_browser_process->profile_manager()->user_data_dir();
7120 }
7121
7122 bool ChromeContentBrowserClient::ShouldSandboxAudioService() {
7123   return IsAudioServiceSandboxEnabled();
7124 }
7125
7126 bool ChromeContentBrowserClient::ShouldSandboxNetworkService() {
7127   return SystemNetworkContextManager::IsNetworkSandboxEnabled();
7128 }
7129
7130 bool ChromeContentBrowserClient::ShouldRunOutOfProcessSystemDnsResolution() {
7131 // This enterprise policy is supported on Android, but the feature will not be
7132 // launched there.
7133 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
7134   // This is possibly called before `g_browser_process` is initialized.
7135   PrefService* local_state;
7136   if (g_browser_process) {
7137     local_state = g_browser_process->local_state();
7138   } else {
7139     local_state = startup_data_.chrome_feature_list_creator()->local_state();
7140   }
7141   if (local_state && local_state->HasPrefPath(
7142                          prefs::kOutOfProcessSystemDnsResolutionEnabled)) {
7143     return local_state->GetBoolean(
7144         prefs::kOutOfProcessSystemDnsResolutionEnabled);
7145   }
7146 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID)
7147
7148   return ContentBrowserClient::ShouldRunOutOfProcessSystemDnsResolution();
7149 }
7150
7151 void ChromeContentBrowserClient::LogWebFeatureForCurrentPage(
7152     content::RenderFrameHost* render_frame_host,
7153     blink::mojom::WebFeature feature) {
7154   DCHECK_CURRENTLY_ON(BrowserThread::UI);
7155   page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage(
7156       render_frame_host, feature);
7157 }
7158
7159 std::string ChromeContentBrowserClient::GetProduct() {
7160   return std::string(version_info::GetProductNameAndVersionForUserAgent());
7161 }
7162
7163 std::string ChromeContentBrowserClient::GetUserAgent() {
7164   return embedder_support::GetUserAgent();
7165 }
7166
7167 std::string ChromeContentBrowserClient::GetUserAgentBasedOnPolicy(
7168     content::BrowserContext* context) {
7169   const PrefService* prefs = Profile::FromBrowserContext(context)->GetPrefs();
7170   embedder_support::UserAgentReductionEnterprisePolicyState
7171       user_agent_reduction =
7172           embedder_support::GetUserAgentReductionFromPrefs(prefs);
7173   return embedder_support::GetUserAgent(user_agent_reduction);
7174 }
7175
7176 blink::UserAgentMetadata ChromeContentBrowserClient::GetUserAgentMetadata() {
7177   DCHECK_CURRENTLY_ON(BrowserThread::UI);
7178   return embedder_support::GetUserAgentMetadata(
7179       g_browser_process->local_state());
7180 }
7181
7182 absl::optional<gfx::ImageSkia> ChromeContentBrowserClient::GetProductLogo() {
7183   // This icon is available on Android, but adds 19KiB to the APK. Since it
7184   // isn't used on Android we exclude it to avoid bloat.
7185 #if !BUILDFLAG(IS_ANDROID)
7186   return absl::optional<gfx::ImageSkia>(
7187       *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
7188           IDR_PRODUCT_LOGO_256));
7189 #else
7190   return absl::nullopt;
7191 #endif
7192 }
7193
7194 bool ChromeContentBrowserClient::IsBuiltinComponent(
7195     content::BrowserContext* browser_context,
7196     const url::Origin& origin) {
7197 #if BUILDFLAG(ENABLE_EXTENSIONS)
7198   return ChromeContentBrowserClientExtensionsPart::IsBuiltinComponent(
7199       browser_context, origin);
7200 #else
7201   return false;
7202 #endif
7203 }
7204
7205 bool ChromeContentBrowserClient::ShouldBlockRendererDebugURL(
7206     const GURL& url,
7207     content::BrowserContext* context,
7208     content::RenderFrameHost* render_frame_host) {
7209 #if !BUILDFLAG(IS_ANDROID)
7210   // If devtools access is blocked for the page, debug URLs should also be
7211   // blocked for the page.
7212   Profile* profile = Profile::FromBrowserContext(context);
7213   content::WebContents* web_contents =
7214       content::WebContents::FromRenderFrameHost(render_frame_host);
7215   if (!DevToolsWindow::AllowDevToolsFor(profile, web_contents)) {
7216     return true;
7217   }
7218 #endif
7219
7220   // If the debug URL being visited is listed in the URLBlocklist policy it
7221   // should be blocked.
7222   PolicyBlocklistService* service =
7223       PolicyBlocklistFactory::GetForBrowserContext(context);
7224   using URLBlocklistState = policy::URLBlocklist::URLBlocklistState;
7225   URLBlocklistState blocklist_state = service->GetURLBlocklistState(url);
7226   return blocklist_state == URLBlocklistState::URL_IN_BLOCKLIST;
7227 }
7228
7229 ui::AXMode ChromeContentBrowserClient::GetAXModeForBrowserContext(
7230     content::BrowserContext* browser_context) {
7231   Profile* profile = Profile::FromBrowserContext(browser_context);
7232   ui::AXMode ax_mode =
7233       content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
7234
7235   // TODO(accessibility): Dynamically create AccessibilityLabelsService and
7236   // destroy it when unused.
7237   auto* labels_service =
7238       AccessibilityLabelsServiceFactory::GetForProfile(profile);
7239   if (labels_service && labels_service->IsEnabled()) {
7240     ax_mode.set_mode(ui::AXMode::kLabelImages, true);
7241   }
7242 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
7243   if (features::IsPdfOcrEnabled() &&
7244       accessibility_state_utils::IsScreenReaderEnabled()) {
7245     // PdfOcrController will be created when the user turns on a screen reader
7246     // before or even after starting the browser.
7247     auto* pdf_ocr_controller =
7248         screen_ai::PdfOcrControllerFactory::GetForProfile(profile);
7249     if (pdf_ocr_controller && pdf_ocr_controller->IsEnabled()) {
7250       ax_mode.set_mode(ui::AXMode::kPDFOcr, true);
7251     }
7252   }
7253 #endif  // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
7254   return ax_mode;
7255 }
7256
7257 #if BUILDFLAG(IS_ANDROID)
7258 content::ContentBrowserClient::WideColorGamutHeuristic
7259 ChromeContentBrowserClient::GetWideColorGamutHeuristic() {
7260   if (viz::AlwaysUseWideColorGamut() ||
7261       features::IsDynamicColorGamutEnabled()) {
7262     return WideColorGamutHeuristic::kUseDisplay;
7263   }
7264
7265   if (display::HasForceDisplayColorProfile() &&
7266       display::GetForcedDisplayColorProfile() ==
7267           gfx::ColorSpace::CreateDisplayP3D65()) {
7268     return WideColorGamutHeuristic::kUseDisplay;
7269   }
7270
7271   return WideColorGamutHeuristic::kNone;
7272 }
7273 #endif
7274
7275 base::flat_set<std::string>
7276 ChromeContentBrowserClient::GetPluginMimeTypesWithExternalHandlers(
7277     content::BrowserContext* browser_context) {
7278   base::flat_set<std::string> mime_types;
7279 #if BUILDFLAG(ENABLE_PLUGINS)
7280   auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context);
7281   for (const auto& pair : map)
7282     mime_types.insert(pair.first);
7283 #endif
7284 #if BUILDFLAG(ENABLE_PDF)
7285   mime_types.insert(pdf::kInternalPluginMimeType);
7286 #endif
7287   return mime_types;
7288 }
7289
7290 void ChromeContentBrowserClient::AugmentNavigationDownloadPolicy(
7291     content::RenderFrameHost* frame_host,
7292     bool user_gesture,
7293     blink::NavigationDownloadPolicy* download_policy) {
7294   const auto* throttle_manager =
7295       subresource_filter::ContentSubresourceFilterThrottleManager::FromPage(
7296           frame_host->GetPage());
7297   if (throttle_manager &&
7298       throttle_manager->IsRenderFrameHostTaggedAsAd(frame_host)) {
7299     download_policy->SetAllowed(blink::NavigationDownloadType::kAdFrame);
7300     if (!user_gesture) {
7301       if (base::FeatureList::IsEnabled(
7302               blink::features::
7303                   kBlockingDownloadsInAdFrameWithoutUserActivation)) {
7304         download_policy->SetDisallowed(
7305             blink::NavigationDownloadType::kAdFrameNoGesture);
7306       } else {
7307         download_policy->SetAllowed(
7308             blink::NavigationDownloadType::kAdFrameNoGesture);
7309       }
7310     }
7311   }
7312 }
7313
7314 bool ChromeContentBrowserClient::HandleTopicsWebApi(
7315     const url::Origin& context_origin,
7316     content::RenderFrameHost* main_frame,
7317     browsing_topics::ApiCallerSource caller_source,
7318     bool get_topics,
7319     bool observe,
7320     std::vector<blink::mojom::EpochTopicPtr>& topics) {
7321   browsing_topics::BrowsingTopicsService* browsing_topics_service =
7322       browsing_topics::BrowsingTopicsServiceFactory::GetForProfile(
7323           Profile::FromBrowserContext(
7324               content::WebContents::FromRenderFrameHost(main_frame)
7325                   ->GetBrowserContext()));
7326
7327   if (!browsing_topics_service)
7328     return {};
7329
7330   bool allowed = browsing_topics_service->HandleTopicsWebApi(
7331       context_origin, main_frame, caller_source, get_topics, observe, topics);
7332
7333   if (main_frame) {
7334     ChromeBrowsingDataModelDelegate::BrowsingDataAccessed(
7335         main_frame, context_origin,
7336         ChromeBrowsingDataModelDelegate::StorageType::kTopics, !allowed);
7337   }
7338
7339   return allowed;
7340 }
7341
7342 int ChromeContentBrowserClient::NumVersionsInTopicsEpochs(
7343     content::RenderFrameHost* main_frame) const {
7344   browsing_topics::BrowsingTopicsService* browsing_topics_service =
7345       browsing_topics::BrowsingTopicsServiceFactory::GetForProfile(
7346           Profile::FromBrowserContext(
7347               content::WebContents::FromRenderFrameHost(main_frame)
7348                   ->GetBrowserContext()));
7349
7350   CHECK(browsing_topics_service);
7351   return browsing_topics_service->NumVersionsInEpochs(
7352       main_frame->GetLastCommittedOrigin());
7353 }
7354
7355 bool ChromeContentBrowserClient::IsBluetoothScanningBlocked(
7356     content::BrowserContext* browser_context,
7357     const url::Origin& requesting_origin,
7358     const url::Origin& embedding_origin) {
7359   const HostContentSettingsMap* const content_settings =
7360       HostContentSettingsMapFactory::GetForProfile(
7361           Profile::FromBrowserContext(browser_context));
7362
7363   if (content_settings->GetContentSetting(
7364           requesting_origin.GetURL(), embedding_origin.GetURL(),
7365           ContentSettingsType::BLUETOOTH_SCANNING) == CONTENT_SETTING_BLOCK) {
7366     return true;
7367   }
7368
7369   return false;
7370 }
7371
7372 void ChromeContentBrowserClient::BlockBluetoothScanning(
7373     content::BrowserContext* browser_context,
7374     const url::Origin& requesting_origin,
7375     const url::Origin& embedding_origin) {
7376   HostContentSettingsMap* const content_settings =
7377       HostContentSettingsMapFactory::GetForProfile(
7378           Profile::FromBrowserContext(browser_context));
7379
7380   content_settings->SetContentSettingDefaultScope(
7381       requesting_origin.GetURL(), embedding_origin.GetURL(),
7382       ContentSettingsType::BLUETOOTH_SCANNING, CONTENT_SETTING_BLOCK);
7383 }
7384
7385 void ChromeContentBrowserClient::GetMediaDeviceIDSalt(
7386     content::RenderFrameHost* rfh,
7387     const net::SiteForCookies& site_for_cookies,
7388     const blink::StorageKey& storage_key,
7389     base::OnceCallback<void(bool, const std::string&)> callback) {
7390   GURL url = rfh->GetLastCommittedURL();
7391   url::Origin top_frame_origin = rfh->GetMainFrame()->GetLastCommittedOrigin();
7392   content::BrowserContext* browser_context = rfh->GetBrowserContext();
7393
7394   // Persistent MediaDevice IDs are allowed if cookies are allowed.
7395   scoped_refptr<content_settings::CookieSettings> cookie_settings =
7396       CookieSettingsFactory::GetForProfile(
7397           Profile::FromBrowserContext(browser_context));
7398   bool allowed = cookie_settings->IsFullCookieAccessAllowed(
7399       url, site_for_cookies, top_frame_origin,
7400       cookie_settings->SettingOverridesForStorage());
7401   ChromeBrowsingDataModelDelegate::BrowsingDataAccessed(
7402       rfh, storage_key,
7403       ChromeBrowsingDataModelDelegate::StorageType::kMediaDeviceSalt, !allowed);
7404   media_device_salt::MediaDeviceSaltService* salt_service =
7405       MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext(
7406           browser_context);
7407   if (!allowed || !salt_service) {
7408     // Use ephemeral salt.
7409     std::move(callback).Run(allowed, browser_context->UniqueId());
7410     return;
7411   }
7412
7413   salt_service->GetSalt(rfh->GetStorageKey(),
7414                         base::BindOnce(std::move(callback), allowed));
7415 }
7416
7417 #if !BUILDFLAG(IS_ANDROID)
7418 base::OnceClosure ChromeContentBrowserClient::FetchRemoteSms(
7419     content::WebContents* web_contents,
7420     const std::vector<url::Origin>& origin_list,
7421     base::OnceCallback<void(absl::optional<std::vector<url::Origin>>,
7422                             absl::optional<std::string>,
7423                             absl::optional<content::SmsFetchFailureType>)>
7424         callback) {
7425   return ::FetchRemoteSms(web_contents, origin_list, std::move(callback));
7426 }
7427 #endif
7428
7429 bool ChromeContentBrowserClient::IsClipboardPasteAllowed(
7430     content::RenderFrameHost* render_frame_host) {
7431   DCHECK(render_frame_host);
7432
7433   // Paste requires either (1) user activation, ...
7434   if (WebContents::FromRenderFrameHost(render_frame_host)
7435           ->HasRecentInteraction()) {
7436     return true;
7437   }
7438
7439   // (2) granted web permission, ...
7440   content::BrowserContext* browser_context =
7441       render_frame_host->GetBrowserContext();
7442   content::PermissionController* permission_controller =
7443       browser_context->GetPermissionController();
7444   blink::mojom::PermissionStatus status =
7445       permission_controller->GetPermissionStatusForCurrentDocument(
7446           blink::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host);
7447   if (status == blink::mojom::PermissionStatus::GRANTED)
7448     return true;
7449
7450 #if BUILDFLAG(ENABLE_EXTENSIONS)
7451   // (3) origination directly from a Chrome extension, ...
7452   Profile* profile = Profile::FromBrowserContext(browser_context);
7453   DCHECK(profile);
7454   const GURL& url =
7455       render_frame_host->GetMainFrame()->GetLastCommittedOrigin().GetURL();
7456   auto* registry = extensions::ExtensionRegistry::Get(profile);
7457   if (url.SchemeIs(extensions::kExtensionScheme)) {
7458     return URLHasExtensionPermission(extensions::ProcessMap::Get(profile),
7459                                      registry, url,
7460                                      render_frame_host->GetProcess()->GetID(),
7461                                      APIPermissionID::kClipboardRead);
7462   }
7463
7464   // or (4) origination from a process that at least might be running a
7465   // content script from an extension with the clipboardRead permission.
7466   // Note that we currently don't allow clipboard operations based just on user
7467   // script injections.
7468   extensions::ExtensionIdSet extension_ids = extensions::
7469       ScriptInjectionTracker::GetExtensionsThatRanContentScriptsInProcess(
7470           *render_frame_host->GetProcess());
7471   for (const auto& extension_id : extension_ids) {
7472     const Extension* extension =
7473         registry->enabled_extensions().GetByID(extension_id);
7474     if (extension && extension->permissions_data()->HasAPIPermission(
7475                          APIPermissionID::kClipboardRead)) {
7476       return true;
7477     }
7478   }
7479 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
7480
7481   return false;
7482 }
7483
7484 void ChromeContentBrowserClient::IsClipboardPasteContentAllowed(
7485     content::WebContents* web_contents,
7486     const GURL& url,
7487     const ui::ClipboardFormatType& data_type,
7488     ClipboardPasteData clipboard_paste_data,
7489     IsClipboardPasteContentAllowedCallback callback) {
7490 #if BUILDFLAG(FULL_SAFE_BROWSING)
7491   Profile* profile =
7492       Profile::FromBrowserContext(web_contents->GetBrowserContext());
7493   bool is_files = data_type == ui::ClipboardFormatType::FilenamesType();
7494   enterprise_connectors::AnalysisConnector connector =
7495       is_files ? enterprise_connectors::AnalysisConnector::FILE_ATTACHED
7496                : enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY;
7497   enterprise_connectors::ContentAnalysisDelegate::Data dialog_data;
7498
7499   if (!enterprise_connectors::ContentAnalysisDelegate::IsEnabled(
7500           profile, web_contents->GetLastCommittedURL(), &dialog_data,
7501           connector)) {
7502     std::move(callback).Run(std::move(clipboard_paste_data));
7503     return;
7504   }
7505
7506   dialog_data.reason =
7507       enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE;
7508
7509   if (is_files) {
7510     auto string_paths = std::move(clipboard_paste_data.file_paths);
7511     std::vector<base::FilePath> paths;
7512     paths.reserve(string_paths.size());
7513     base::ranges::transform(string_paths, std::back_inserter(paths),
7514                             base::FilePath::FromASCII);
7515     auto fsd = std::make_unique<enterprise_connectors::FilesScanData>(paths);
7516     auto* fsd_ptr = fsd.get();
7517     fsd_ptr->ExpandPaths(base::BindOnce(&HandleExpandedPaths, std::move(fsd),
7518                                         web_contents->GetWeakPtr(),
7519                                         std::move(dialog_data), connector,
7520                                         std::move(paths), std::move(callback)));
7521   } else {
7522     dialog_data.text.push_back(clipboard_paste_data.text);
7523     // Send image only to local agent for analysis.
7524     if (dialog_data.settings.cloud_or_local_settings.is_local_analysis()) {
7525       dialog_data.image = std::move(clipboard_paste_data.image);
7526     }
7527     HandleStringData(web_contents, std::move(dialog_data), connector,
7528                      std::move(callback));
7529   }
7530 #else
7531   std::move(callback).Run(std::move(clipboard_paste_data));
7532 #endif  // BUILDFLAG(FULL_SAFE_BROWSING)
7533 }
7534
7535 bool ChromeContentBrowserClient::IsClipboardCopyAllowed(
7536     content::BrowserContext* browser_context,
7537     const GURL& url,
7538     size_t data_size_in_bytes,
7539     std::u16string& replacement_data) {
7540   ClipboardRestrictionService* service =
7541       ClipboardRestrictionServiceFactory::GetInstance()->GetForBrowserContext(
7542           browser_context);
7543   return service->IsUrlAllowedToCopy(url, data_size_in_bytes,
7544                                      &replacement_data);
7545 }
7546
7547 #if BUILDFLAG(ENABLE_VR)
7548 content::XrIntegrationClient*
7549 ChromeContentBrowserClient::GetXrIntegrationClient() {
7550   if (!xr_integration_client_)
7551     xr_integration_client_ = std::make_unique<vr::ChromeXrIntegrationClient>(
7552         base::PassKey<ChromeContentBrowserClient>());
7553   return xr_integration_client_.get();
7554 }
7555 #endif  // BUILDFLAG(ENABLE_VR)
7556
7557 void ChromeContentBrowserClient::BindBrowserControlInterface(
7558     mojo::ScopedMessagePipeHandle pipe) {
7559 #if BUILDFLAG(IS_CHROMEOS_LACROS)
7560   chromeos::LacrosService::Get()->BindReceiver(
7561       chrome::GetVersionString(chrome::WithExtendedStable(true)));
7562 #endif
7563 }
7564
7565 bool ChromeContentBrowserClient::
7566     ShouldInheritCrossOriginEmbedderPolicyImplicitly(const GURL& url) {
7567 #if BUILDFLAG(ENABLE_EXTENSIONS)
7568   return url.SchemeIs(extensions::kExtensionScheme);
7569 #else
7570   return false;
7571 #endif
7572 }
7573
7574 bool ChromeContentBrowserClient::
7575     ShouldServiceWorkerInheritPolicyContainerFromCreator(const GURL& url) {
7576   if (url.SchemeIsLocal()) {
7577     return true;
7578   }
7579 #if BUILDFLAG(ENABLE_EXTENSIONS)
7580   return url.SchemeIs(extensions::kExtensionScheme);
7581 #else
7582   return false;
7583 #endif
7584 }
7585
7586 content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride
7587 ChromeContentBrowserClient::ShouldOverridePrivateNetworkRequestPolicy(
7588     content::BrowserContext* browser_context,
7589     const url::Origin& origin) {
7590   // The host content settings map might no be null for some irregular profiles,
7591   // e.g. the System Profile.
7592   if (HostContentSettingsMap* service =
7593           HostContentSettingsMapFactory::GetForProfile(browser_context)) {
7594     if (content_settings::ShouldAllowInsecurePrivateNetworkRequests(service,
7595                                                                     origin)) {
7596       return content::ContentBrowserClient::
7597           PrivateNetworkRequestPolicyOverride::kForceAllow;
7598     }
7599   }
7600
7601 #if BUILDFLAG(IS_ANDROID)
7602   if (base::FeatureList::IsEnabled(
7603           kPrivateNetworkAccessRestrictionsForAutomotive) &&
7604       base::android::BuildInfo::GetInstance()->is_automotive()) {
7605     return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride::
7606         kBlockInsteadOfWarn;
7607   }
7608 #endif
7609
7610   Profile* profile = Profile::FromBrowserContext(browser_context);
7611   if (profile->GetPrefs()->GetBoolean(
7612           prefs::kManagedPrivateNetworkAccessRestrictionsEnabled)) {
7613     return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride::
7614         kBlockInsteadOfWarn;
7615   }
7616
7617   return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride::
7618       kDefault;
7619 }
7620
7621 bool ChromeContentBrowserClient::IsJitDisabledForSite(
7622     content::BrowserContext* browser_context,
7623     const GURL& site_url) {
7624   Profile* profile = Profile::FromBrowserContext(browser_context);
7625   auto* map = HostContentSettingsMapFactory::GetForProfile(profile);
7626   // Special case to determine if any policy is set.
7627   if (map && site_url.is_empty()) {
7628     return map->GetDefaultContentSetting(ContentSettingsType::JAVASCRIPT_JIT,
7629                                          nullptr) == CONTENT_SETTING_BLOCK;
7630   }
7631
7632   // Only disable JIT for web schemes.
7633   if (!site_url.SchemeIsHTTPOrHTTPS())
7634     return false;
7635
7636   return (map && map->GetContentSetting(site_url, site_url,
7637                                         ContentSettingsType::JAVASCRIPT_JIT) ==
7638                      CONTENT_SETTING_BLOCK);
7639 }
7640
7641 ukm::UkmService* ChromeContentBrowserClient::GetUkmService() {
7642   return g_browser_process->GetMetricsServicesManager()->GetUkmService();
7643 }
7644
7645 blink::mojom::OriginTrialsSettingsPtr
7646 ChromeContentBrowserClient::GetOriginTrialsSettings() {
7647   return g_browser_process->GetOriginTrialsSettingsStorage()->GetSettings();
7648 }
7649
7650 void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
7651     content::BrowserContext* context) {
7652 #if !BUILDFLAG(IS_ANDROID)
7653   DVLOG(1) << "OnKeepaliveRequestStarted: " << num_keepalive_requests_
7654            << " ==> " << num_keepalive_requests_ + 1;
7655   ++num_keepalive_requests_;
7656   DCHECK_GT(num_keepalive_requests_, 0u);
7657
7658   if (!context) {
7659     // We somehow failed to associate the request and the BrowserContext. Bail
7660     // out.
7661     return;
7662   }
7663
7664   const auto now = base::TimeTicks::Now();
7665   const auto timeout = GetKeepaliveTimerTimeout(context);
7666   keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
7667   if (keepalive_deadline_ > now && !keepalive_timer_.IsRunning()) {
7668     DVLOG(1) << "Starting a keepalive timer(" << timeout.InSecondsF()
7669              << " seconds)";
7670     keepalive_timer_.Start(
7671         FROM_HERE, keepalive_deadline_ - now,
7672         base::BindOnce(
7673             &ChromeContentBrowserClient::OnKeepaliveTimerFired,
7674             weak_factory_.GetWeakPtr(),
7675             std::make_unique<ScopedKeepAlive>(
7676                 KeepAliveOrigin::BROWSER, KeepAliveRestartOption::DISABLED)));
7677   }
7678 #endif  // !BUILDFLAG(IS_ANDROID)
7679 }
7680
7681 void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
7682 #if !BUILDFLAG(IS_ANDROID)
7683   DCHECK_GT(num_keepalive_requests_, 0u);
7684   DVLOG(1) << "OnKeepaliveRequestFinished: " << num_keepalive_requests_
7685            << " ==> " << num_keepalive_requests_ - 1;
7686   --num_keepalive_requests_;
7687   if (num_keepalive_requests_ == 0) {
7688     DVLOG(1) << "Stopping the keepalive timer";
7689     keepalive_timer_.Stop();
7690     // This deletes the keep alive handle attached to the timer function and
7691     // unblock the shutdown sequence.
7692   }
7693 #endif  // !BUILDFLAG(IS_ANDROID)
7694 }
7695
7696 #if BUILDFLAG(IS_MAC)
7697 bool ChromeContentBrowserClient::SetupEmbedderSandboxParameters(
7698     sandbox::mojom::Sandbox sandbox_type,
7699     sandbox::SandboxCompiler* compiler) {
7700   if (sandbox_type == sandbox::mojom::Sandbox::kSpeechRecognition) {
7701     base::FilePath soda_component_path = speech::GetSodaDirectory();
7702     CHECK(!soda_component_path.empty());
7703     CHECK(compiler->SetParameter(sandbox::policy::kParamSodaComponentPath,
7704                                  soda_component_path.value()));
7705
7706     base::FilePath soda_language_pack_path =
7707         speech::GetSodaLanguagePacksDirectory();
7708     CHECK(!soda_language_pack_path.empty());
7709     CHECK(compiler->SetParameter(sandbox::policy::kParamSodaLanguagePackPath,
7710                                  soda_language_pack_path.value()));
7711     return true;
7712 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
7713   } else if (sandbox_type == sandbox::mojom::Sandbox::kScreenAI) {
7714     // ScreenAI service needs read access to ScreenAI component path, so that it
7715     // would be able to find the latest downloaded version, and load its binary
7716     // and all enclosed model files.
7717     base::FilePath screen_ai_component_dir = screen_ai::GetComponentDir();
7718     if (screen_ai_component_dir.empty()) {
7719       VLOG(1) << "Screen AI component not found.";
7720       return false;
7721     }
7722
7723     CHECK(compiler->SetParameter(sandbox::policy::kParamScreenAiComponentPath,
7724                                  screen_ai_component_dir.value()));
7725
7726     return true;
7727 #endif
7728   }
7729
7730   return false;
7731 }
7732
7733 #endif  // BUILDFLAG(IS_MAC)
7734
7735 void ChromeContentBrowserClient::GetHyphenationDictionary(
7736     base::OnceCallback<void(const base::FilePath&)> callback) {
7737 #if BUILDFLAG(USE_MINIKIN_HYPHENATION) && !BUILDFLAG(IS_ANDROID)
7738   component_updater::HyphenationComponentInstallerPolicy::
7739       GetHyphenationDictionary(std::move(callback));
7740 #endif
7741 }
7742
7743 bool ChromeContentBrowserClient::HasErrorPage(int http_status_code) {
7744   // Use an internal error page, if we have one for the status code.
7745   return error_page::LocalizedError::HasStrings(
7746       error_page::Error::kHttpErrorDomain, http_status_code);
7747 }
7748
7749 std::unique_ptr<content::IdentityRequestDialogController>
7750 ChromeContentBrowserClient::CreateIdentityRequestDialogController(
7751     content::WebContents* web_contents) {
7752   return std::make_unique<IdentityDialogController>(web_contents);
7753 }
7754
7755 bool ChromeContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs(
7756     content::BrowserContext* browser_context) {
7757   Profile* profile = Profile::FromBrowserContext(browser_context);
7758   if (!profile->GetPrefs()->GetBoolean(
7759           prefs::kSuppressDifferentOriginSubframeJSDialogs)) {
7760     return false;
7761   }
7762   return ContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs(
7763       browser_context);
7764 }
7765
7766 bool ChromeContentBrowserClient::IsFindInPageDisabledForOrigin(
7767     const url::Origin& origin) {
7768 #if BUILDFLAG(ENABLE_PDF)
7769   // For PDF viewing with the PPAPI-free PDF Viewer, find-in-page should only
7770   // display results from the PDF content, and not from the UI.
7771   return IsPdfExtensionOrigin(origin);
7772 #else
7773   return false;
7774 #endif
7775 }
7776
7777 std::unique_ptr<content::AnchorElementPreconnectDelegate>
7778 ChromeContentBrowserClient::CreateAnchorElementPreconnectDelegate(
7779     content::RenderFrameHost& render_frame_host) {
7780   return std::make_unique<AnchorElementPreloader>(render_frame_host);
7781 }
7782
7783 std::unique_ptr<content::SpeculationHostDelegate>
7784 ChromeContentBrowserClient::CreateSpeculationHostDelegate(
7785     content::RenderFrameHost& render_frame_host) {
7786   return std::make_unique<ChromeSpeculationHostDelegate>(render_frame_host);
7787 }
7788
7789 std::unique_ptr<content::PrefetchServiceDelegate>
7790 ChromeContentBrowserClient::CreatePrefetchServiceDelegate(
7791     content::BrowserContext* browser_context) {
7792   return std::make_unique<ChromePrefetchServiceDelegate>(browser_context);
7793 }
7794
7795 std::unique_ptr<content::PrerenderWebContentsDelegate>
7796 ChromeContentBrowserClient::CreatePrerenderWebContentsDelegate() {
7797   return std::make_unique<PrerenderWebContentsDelegateImpl>();
7798 }
7799
7800 void ChromeContentBrowserClient::OnWebContentsCreated(
7801     content::WebContents* web_contents) {
7802   // NOTE: Please don't add additional code to this method - attaching universal
7803   // WebContentsObservers goes through the separate function, to ensure that the
7804   // (rare) additions of universal helpers are code reviewed by separate OWNERS.
7805   AttachUniversalWebContentsObservers(web_contents);
7806 }
7807
7808 #if !BUILDFLAG(IS_ANDROID)
7809 base::TimeDelta ChromeContentBrowserClient::GetKeepaliveTimerTimeout(
7810     content::BrowserContext* context) {
7811   Profile* profile = Profile::FromBrowserContext(context);
7812   PrefService* prefs = profile->GetPrefs();
7813   if (!prefs) {
7814     return base::TimeDelta();
7815   }
7816
7817   const int seconds =
7818       prefs->GetInteger(prefs::kFetchKeepaliveDurationOnShutdown);
7819   // The preference is set only be the corresponding enterprise policy, and
7820   // we have minimum/maximum values on it.
7821   DCHECK_LE(0, seconds);
7822   DCHECK_LE(seconds, 5);
7823   return base::Seconds(seconds);
7824 }
7825
7826 void ChromeContentBrowserClient::OnKeepaliveTimerFired(
7827     std::unique_ptr<ScopedKeepAlive> keep_alive_handle) {
7828   const auto now = base::TimeTicks::Now();
7829   const auto then = keepalive_deadline_;
7830   if (now < then) {
7831     keepalive_timer_.Start(
7832         FROM_HERE, then - now,
7833         base::BindOnce(&ChromeContentBrowserClient::OnKeepaliveTimerFired,
7834                        weak_factory_.GetWeakPtr(),
7835                        std::move(keep_alive_handle)));
7836   }
7837 }
7838 #endif
7839
7840 bool ChromeContentBrowserClient::ShouldPreconnectNavigation(
7841     content::BrowserContext* browser_context) {
7842 #if BUILDFLAG(ENABLE_EXTENSIONS)
7843   // An extension could be blocking connections for privacy reasons, so skip
7844   // optimization if there are any extensions with WebRequest permissions.
7845   const auto* web_request_api =
7846       extensions::BrowserContextKeyedAPIFactory<extensions::WebRequestAPI>::Get(
7847           browser_context);
7848   if (!web_request_api || web_request_api->MayHaveProxies())
7849     return false;
7850 #endif
7851   return prefetch::IsSomePreloadingEnabled(
7852              *Profile::FromBrowserContext(browser_context)->GetPrefs()) ==
7853          content::PreloadingEligibility::kEligible;
7854 }
7855
7856 bool ChromeContentBrowserClient::ShouldDisableOriginAgentClusterDefault(
7857     content::BrowserContext* browser_context) {
7858   // The enterprise policy for kOriginAgentClusterDefaultEnabled defaults to
7859   // true to defer to Chromium's decision. If it is set to false, it should
7860   // override Chromium's decision and use site-keyed agent clusters by default
7861   // instead.
7862   return !Profile::FromBrowserContext(browser_context)
7863               ->GetPrefs()
7864               ->GetBoolean(prefs::kOriginAgentClusterDefaultEnabled);
7865 }
7866
7867 bool ChromeContentBrowserClient::WillProvidePublicFirstPartySets() {
7868 #if BUILDFLAG(ENABLE_COMPONENT_UPDATER)
7869   return !is_minimal_mode_ &&
7870          !base::CommandLine::ForCurrentProcess()->HasSwitch(
7871              switches::kDisableComponentUpdate) &&
7872          base::FeatureList::IsEnabled(features::kFirstPartySets);
7873 #else
7874   return false;
7875 #endif  // BUILDFLAG(ENABLE_COMPONENT_UPDATER)
7876 }
7877
7878 content::mojom::AlternativeErrorPageOverrideInfoPtr
7879 ChromeContentBrowserClient::GetAlternativeErrorPageOverrideInfo(
7880     const GURL& url,
7881     content::RenderFrameHost* render_frame_host,
7882     content::BrowserContext* browser_context,
7883     int32_t error_code) {
7884 #if !BUILDFLAG(IS_ANDROID)
7885   if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(
7886           browser_context) &&
7887       url.SchemeIs(chrome::kIsolatedAppScheme)) {
7888     content::mojom::AlternativeErrorPageOverrideInfoPtr
7889         alternative_error_page_override_info =
7890             web_app::MaybeGetIsolatedWebAppErrorPageInfo(
7891                 url, render_frame_host, browser_context, error_code);
7892     if (alternative_error_page_override_info) {
7893       alternative_error_page_override_info->alternative_error_page_params.Set(
7894           error_page::kOverrideErrorPage, base::Value(true));
7895       return alternative_error_page_override_info;
7896     }
7897   }
7898 #endif
7899
7900   if (base::FeatureList::IsEnabled(features::kPWAsDefaultOfflinePage) &&
7901       error_code == net::ERR_INTERNET_DISCONNECTED) {
7902     content::mojom::AlternativeErrorPageOverrideInfoPtr
7903         alternative_error_page_override_info = web_app::GetOfflinePageInfo(
7904             url, render_frame_host, browser_context);
7905     if (alternative_error_page_override_info) {
7906       // Use the alternative error page dictionary to override the error page.
7907       alternative_error_page_override_info->alternative_error_page_params.Set(
7908           error_page::kOverrideErrorPage, base::Value(true));
7909       web_app::TrackOfflinePageVisibility(render_frame_host);
7910       return alternative_error_page_override_info;
7911     }
7912   }
7913
7914 #if BUILDFLAG(IS_CHROMEOS_ASH)
7915   using PortalState = chromeos::network_config::mojom::PortalState;
7916   auto portal_state = ash::network_health::NetworkHealthManager::GetInstance()
7917                           ->helper()
7918                           ->WiFiPortalState();
7919   if (portal_state != PortalState::kUnknown) {
7920     auto alternative_error_page_override_info =
7921         content::mojom::AlternativeErrorPageOverrideInfo::New();
7922     bool is_portal_state = portal_state == PortalState::kPortal ||
7923                            portal_state == PortalState::kPortalSuspected ||
7924                            portal_state == PortalState::kProxyAuthRequired;
7925     // Use the alternative error page dictionary to provide additional
7926     // suggestions in the default error page.
7927     alternative_error_page_override_info->alternative_error_page_params.Set(
7928         error_page::kOverrideErrorPage, base::Value(false));
7929     alternative_error_page_override_info->alternative_error_page_params.Set(
7930         error_page::kIsPortalStateKey, base::Value(is_portal_state));
7931     return alternative_error_page_override_info;
7932   }
7933 #endif
7934
7935   return nullptr;
7936 }
7937
7938 void ChromeContentBrowserClient::OnSharedStorageWorkletHostCreated(
7939     content::RenderFrameHost* rfh) {
7940   if (auto* observer =
7941           page_load_metrics::MetricsWebContentsObserver::FromWebContents(
7942               WebContents::FromRenderFrameHost(rfh))) {
7943     observer->OnSharedStorageWorkletHostCreated(rfh);
7944   }
7945 }
7946
7947 bool ChromeContentBrowserClient::ShouldSendOutermostOriginToRenderer(
7948     const url::Origin& outermost_origin) {
7949 #if BUILDFLAG(ENABLE_EXTENSIONS)
7950   // We only want to send the outermost origin if it is an extension scheme.
7951   // We do not send the outermost origin to every renderer to avoid leaking
7952   // additional information into the renderer about the embedder. For
7953   // extensions though this is required for the way content injection API
7954   // works. We do not want one extension injecting content into the context
7955   // of another extension.
7956   return outermost_origin.scheme() == extensions::kExtensionScheme;
7957 #else
7958   return false;
7959 #endif
7960 }
7961
7962 bool ChromeContentBrowserClient::IsFileSystemURLNavigationAllowed(
7963     content::BrowserContext* browser_context,
7964     const GURL& url) {
7965 #if BUILDFLAG(ENABLE_EXTENSIONS)
7966   // filesystem: URLs for Chrome Apps are in the following format:
7967   // `filesystem:chrome-extension://<extension-id>/...`
7968   if (!url.SchemeIsFileSystem())
7969     return false;
7970   // Once converted into an origin, we expect the following:
7971   // scheme() is chrome-extension: (filesystem: is automatically discarded)
7972   // host() is the extension-id
7973   const url::Origin origin = url::Origin::Create(url);
7974   if (origin.scheme() == extensions::kExtensionScheme) {
7975     const Extension* extension =
7976         extensions::ExtensionRegistry::Get(browser_context)
7977             ->enabled_extensions()
7978             .GetByID(origin.host());
7979     DCHECK(extension);
7980     return extension->is_platform_app();
7981   }
7982 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
7983   return false;
7984 }
7985
7986 bool ChromeContentBrowserClient::AreIsolatedWebAppsEnabled(
7987     content::BrowserContext* browser_context) {
7988 #if !BUILDFLAG(IS_ANDROID)
7989   Profile* profile = Profile::FromBrowserContext(browser_context);
7990   if (!web_app::AreWebAppsEnabled(profile)) {
7991     return false;
7992   }
7993
7994 #if BUILDFLAG(IS_CHROMEOS)
7995   // Check if the enterprise policy that regulates Isolated Web Apps force
7996   // installing is present. If it is there then the IWAs should be enabled.
7997   const base::Value::List& isolated_web_apps =
7998       profile->GetPrefs()->GetList(prefs::kIsolatedWebAppInstallForceList);
7999   if (!isolated_web_apps.empty()) {
8000     return true;
8001   }
8002 #if BUILDFLAG(IS_CHROMEOS_ASH)
8003   // IWAs should be enabled for ShimlessRMA app profile.
8004   if (ash::IsShimlessRmaAppBrowserContext(browser_context)) {
8005     return true;
8006   }
8007 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
8008 #endif  // BUILDFLAG(IS_CHROMEOS)
8009
8010   if (base::FeatureList::IsEnabled(features::kIsolatedWebApps)) {
8011     return true;
8012   }
8013 #endif  // !BUILDFLAG(IS_ANDROID)
8014
8015   return false;
8016 }
8017
8018 bool ChromeContentBrowserClient::IsThirdPartyStoragePartitioningAllowed(
8019     content::BrowserContext* browser_context,
8020     const url::Origin& top_level_origin) {
8021   const HostContentSettingsMap* const content_settings =
8022       HostContentSettingsMapFactory::GetForProfile(
8023           Profile::FromBrowserContext(browser_context));
8024   if (!content_settings) {
8025     // We fail permissive as this function is used to check whether partitioning
8026     // should be blocked, but isn't the final word on if it's allowed.
8027     return true;
8028   }
8029   return content_settings->GetContentSetting(
8030              top_level_origin.GetURL(), top_level_origin.GetURL(),
8031              ContentSettingsType::THIRD_PARTY_STORAGE_PARTITIONING) ==
8032          CONTENT_SETTING_ALLOW;
8033 }
8034
8035 bool ChromeContentBrowserClient::
8036     IsTransientActivationRequiredForShowFileOrDirectoryPicker(
8037         content::WebContents* web_contents) {
8038 #if !BUILDFLAG(IS_ANDROID)
8039   return IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents);
8040 #else   // !BUILDFLAG(IS_ANDROID)
8041   return true;
8042 #endif  // !BUILDFLAG(IS_ANDROID)
8043 }
8044
8045 #if BUILDFLAG(IS_MAC)
8046 std::string ChromeContentBrowserClient::GetChildProcessSuffix(int child_flags) {
8047   if (child_flags == chrome::kChildProcessHelperAlerts) {
8048     return chrome::kMacHelperSuffixAlerts;
8049   }
8050   NOTREACHED() << "Unsupported child process flags!";
8051   return {};
8052 }
8053 #endif  // BUILDFLAG(IS_MAC)
8054
8055 bool ChromeContentBrowserClient::ShouldUseFirstPartyStorageKey(
8056     const url::Origin& origin) {
8057 #if BUILDFLAG(ENABLE_EXTENSIONS)
8058   return origin.scheme() == extensions::kExtensionScheme;
8059 #else
8060   return false;
8061 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
8062 }
8063
8064 std::unique_ptr<content::ResponsivenessCalculatorDelegate>
8065 ChromeContentBrowserClient::CreateResponsivenessCalculatorDelegate() {
8066 #if !BUILDFLAG(IS_ANDROID)
8067   return ChromeResponsivenessCalculatorDelegate::Create();
8068 #else
8069   return nullptr;
8070 #endif
8071 }
8072
8073 // static
8074 bool ChromeContentBrowserClient::DoesGaiaOriginRequireDedicatedProcess() {
8075 #if !BUILDFLAG(IS_ANDROID)
8076   return true;
8077 #else
8078   // Sign-in process isolation is not strictly needed on Android, see
8079   // https://crbug.com/739418. On Android, it's more optional but it does
8080   // improve security generally and specifically it allows the exposure of
8081   // certain optional privileged APIs.
8082
8083   // Kill switch that falls back to the legacy behavior.
8084   if (!base::FeatureList::IsEnabled(kAllowGaiaOriginIsolationOnAndroid)) {
8085     return false;
8086   }
8087
8088   if (site_isolation::SiteIsolationPolicy::
8089           ShouldDisableSiteIsolationDueToMemoryThreshold(
8090               content::SiteIsolationMode::kPartialSiteIsolation)) {
8091     // Insufficient memory to isolate Gaia's origin.
8092     return false;
8093   }
8094
8095   return true;
8096 #endif  // !BUILDFLAG(IS_ANDROID)
8097 }
8098
8099 bool ChromeContentBrowserClient::CanBackForwardCachedPageReceiveCookieChanges(
8100     content::BrowserContext& browser_context,
8101     const GURL& url,
8102     const net::SiteForCookies& site_for_cookies,
8103     const absl::optional<url::Origin>& top_frame_origin,
8104     const net::CookieSettingOverrides overrides) {
8105   scoped_refptr<content_settings::CookieSettings> cookie_settings =
8106       CookieSettingsFactory::GetForProfile(
8107           Profile::FromBrowserContext(&browser_context));
8108   CHECK(cookie_settings);
8109   return cookie_settings->IsFullCookieAccessAllowed(
8110       url, site_for_cookies, top_frame_origin, overrides);
8111 }
8112
8113 void ChromeContentBrowserClient::GetCloudIdentifiers(
8114     const storage::FileSystemURL& url,
8115     content::FileSystemAccessPermissionContext::HandleType handle_type,
8116     GetCloudIdentifiersCallback callback) {
8117 #if BUILDFLAG(IS_CHROMEOS)
8118   cloud_identifier::GetCloudIdentifierFromAsh(url, handle_type,
8119                                               std::move(callback));
8120 #else   // BUILDFLAG(IS_CHROMEOS)
8121   return ContentBrowserClient::GetCloudIdentifiers(url, handle_type,
8122                                                    std::move(callback));
8123 #endif  // BUILDFLAG(IS_CHROMEOS)
8124 }
8125
8126 bool ChromeContentBrowserClient::
8127     ShouldAllowBackForwardCacheForCacheControlNoStorePage(
8128         content::BrowserContext* browser_context) {
8129   DCHECK_CURRENTLY_ON(BrowserThread::UI);
8130 #if BUILDFLAG(IS_CHROMEOS)
8131   // Do not store CCNS page into BFCache in the kiosk session.
8132   if (chromeos::IsKioskSession()) {
8133     return false;
8134   }
8135 #endif
8136
8137   if (chrome::IsRunningInAppMode()) {
8138     return false;
8139   }
8140
8141   const PrefService::Preference* pref =
8142       Profile::FromBrowserContext(browser_context)
8143           ->GetPrefs()
8144           ->FindPreference(
8145               policy::policy_prefs::
8146                   kAllowBackForwardCacheForCacheControlNoStorePageEnabled);
8147   if (pref && pref->IsManaged() && pref->GetValue()->is_bool()) {
8148     return pref->GetValue()->GetBool();
8149   }
8150   // If the pref is not found or not managed, BFCaching CCNS page should be
8151   // enabled by default.
8152   return true;
8153 }
8154
8155 void ChromeContentBrowserClient::SetIsMinimalMode(bool minimal) {
8156   is_minimal_mode_ = minimal;
8157 }
8158
8159 #if !BUILDFLAG(IS_ANDROID)
8160 void ChromeContentBrowserClient::BindVideoEffectsManager(
8161     const std::string& device_id,
8162     content::BrowserContext* browser_context,
8163     mojo::PendingReceiver<video_capture::mojom::VideoEffectsManager>
8164         video_effects_manager) {
8165   media_effects::BindVideoEffectsManager(device_id, browser_context,
8166                                          std::move(video_effects_manager));
8167 }
8168 #endif  // !BUILDFLAG(IS_ANDROID)